怎样判断一个类型是"操作简单"类型?即持有单个值
typeof(string).IsPrimitive == false
typeof(int).IsPrimitive == true
typeof(MyClass).IsClass == true
typeof(string).IsClass == true
typeof(string).IsByRef == false
typeof(MyClass).IsByRef == true // correction: should be false (see comments below)
我有一个实例T的新实例,如果它是一个复杂类,填充的方法其从一组源数据值的属性。
I have a method that instantiates a new instance of T and, if it's a "complex" class, fills its properties from a set of source data values.
(一)如果T是一个简单的类型(如字符串或int或其他类似的),从快速转换源数据,以T为被执行。
(a) If T is a simple type (e.g. a string or an int or anything else similar), a quick conversion from the source data to T is to be performed.
(二)如果T是一个类(而不是一些简单的像字符串),那么我会使用Activator.CreateInstance和做一点反思来填充字段。
(b) If T is a class (but not something simple like string), then I'll use Activator.CreateInstance and do a bit of reflection to populate the fields.
是否有一个快速和简单的方式告诉我是否应该使用方法(a)或(b)法?这个逻辑将和T泛型方法的类型参数内部使用。
Is there a quick and simple way to tell if I should use method (a) or method (b)? This logic will be used inside a generic method with T as the type argument.
字符串可能是一个特例。
String is probably a special case.
我想我会做.....
I think I would do.....
bool IsSimple(Type type)
{
return type.IsPrimitive
|| type.Equals(typeof(string)));
}
修改:
有时候,你需要支付一些情况下,如枚举和小数。枚举是一种特殊的在C#中的类型。小数像任何其他结构。与结构的问题是,它们可能是复杂的,它们可以是用户定义的类型,它们可以只是一个数字。所以,你没有任何其他的机会比知道它们加以区分。
Sometimes you need to cover some more cases, like enums and decimals. Enums are a special kind of type in C#. Decimals are structs like any other. The problem with the structs is that they may be complex, they may be user defined types, they may be just a number. So you don't have any other chance than knowing them to differentiate.
bool IsSimple(Type type)
{
return type.IsPrimitive
|| type.IsEnum
|| type.Equals(typeof(string))
|| type.Equals(typeof(decimal));
}
处理可空的同行也有点棘手。可空本身是一个结构。
Handling nullable counterparts are also a bit tricky. The nullable itself is a struct.
bool IsSimple(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// nullable type, check if the nested type is simple.
return IsSimple(type.GetGenericArguments()[0]);
}
return type.IsPrimitive
|| type.IsEnum
|| type.Equals(typeof(string))
|| type.Equals(typeof(decimal));
}
测试:
Test:
Assert.IsTrue(IsSimple(typeof(string));
Assert.IsTrue(IsSimple(typeof(int));
Assert.IsTrue(IsSimple(typeof(decimal));
Assert.IsTrue(IsSimple(typeof(float));
Assert.IsTrue(IsSimple(typeof(StringComparison)); // enum
Assert.IsTrue(IsSimple(typeof(int?));
Assert.IsTrue(IsSimple(typeof(decimal?));
Assert.IsTrue(IsSimple(typeof(StringComparison?));
Assert.IsFalse(IsSimple(typeof(object));
Assert.IsFalse(IsSimple(typeof(Point)); // struct
Assert.IsFalse(IsSimple(typeof(Point?));
Assert.IsFalse(IsSimple(typeof(StringBuilder)); // reference type