如何判断类型是否为"简单"类型?即持有单一价值

Nat*_*ley 59 .net c# generics

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)
Run Code Online (Sandbox Code Playgroud)

我有一个实例化T的新实例的方法,如果它是一个"复杂"类,则从一组源数据值中填充其属性.

(a)如果T是简单类型(例如字符串或int或其他类似的东西),则执行从源数据到T的快速转换.

(b)如果T是一个类(但不是像字符串这样简单的东西),那么我将使用Activator.CreateInstance并进行一些反射来填充字段.

是否有一种快速而简单的方法来判断我是否应该使用方法(a)或方法(b)?此逻辑将在通用方法中使用,其中T作为类型参数.

Ste*_*ger 111

字符串可能是一种特殊情况.

我想我会做.....

bool IsSimple(Type type)
{
    return type.IsPrimitive 
      || type.Equals(typeof(string));
}
Run Code Online (Sandbox Code Playgroud)

编辑:

有时您需要涵盖更多案例,如枚举和小数.枚举是C#中的一种特殊类型.小数是任何其他结构.结构的问题在于它们可能很复杂,它们可能是用户定义的类型,它们可能只是一个数字.因此,除了了解它们之外你没有任何其他机会.

bool IsSimple(Type type)
{
  return type.IsPrimitive 
    || type.IsEnum
    || type.Equals(typeof(string))
    || type.Equals(typeof(decimal));
}
Run Code Online (Sandbox Code Playgroud)

处理可空的对应物也有点棘手.可空的本身就是一个结构.

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));
}
Run Code Online (Sandbox Code Playgroud)

测试:

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 in System.Drawing
Assert.IsFalse(IsSimple(typeof(Point?)));
Assert.IsFalse(IsSimple(typeof(StringBuilder))); // reference type
Run Code Online (Sandbox Code Playgroud)

注意.NET Core

正如DucoJ在他的回答中指出的那样,一些已使用的方法Type在.NET核心中不再可用.

固定代码(我希望它有效,我无法尝试自己.否则请评论):

bool IsSimple(Type type)
{
  var typeInfo = type.GetTypeInfo();
  if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
  {
    // nullable type, check if the nested type is simple.
    return IsSimple(typeInfo.GetGenericArguments()[0]);
  }
  return typeInfo.IsPrimitive 
    || typeInfo.IsEnum
    || type.Equals(typeof(string))
    || type.Equals(typeof(decimal));
}
Run Code Online (Sandbox Code Playgroud)

  • 根据您的需要,您可能需要添加** || type.Equals(typeof(datetime))** (2认同)

小智 16

除了Stefan Steinegger之外,回答:在.NET Core中,.IsPrimitive等不再是Type的成员,它们现在是TypeInfo的成员.那么他的解决方案将成为:

bool IsSimple(TypeInfo type)
{
    if (type.IsGenericType && type.GetGenericTypeDefinition() ==     typeof(Nullable<>))
    {
        // nullable type, check if the nested type is simple.
        return IsSimple((type.GetGenericArguments()[0]).GetTypeInfo());
    }
    return type.IsPrimitive
      || type.IsEnum
      || type.Equals(typeof(string))
      || type.Equals(typeof(decimal));
}
Run Code Online (Sandbox Code Playgroud)


Mau*_*ser 6

有一个比原始类型更通用的类型,ValueType包含的内容比原始类型要多得多,例如枚举,十进制以及其他类似ValueType的东西。下面是我编写的用于识别可能适合您的复杂类型的函数。

    public static bool IsComplex(Type typeIn)
    {
        if (typeIn.IsSubclassOf(typeof(System.ValueType)) || typeIn.Equals(typeof(string))) //|| typeIn.IsPrimitive
            return false;
        else
            return true;

    }
Run Code Online (Sandbox Code Playgroud)

  • 还有`typeIn.IsValueType`。在这种情况下,“ IsComplex”具有误导性,因为结构(值类型)由于具有许多属性(例如可以指向引用类型)而变得复杂。 (2认同)

jul*_*gon 5

使用基于 的解决方案TypeConverter也是一种很好且简单的建模方法。

假设你有这个实现:

public static bool IsSimple(this Type type) =>
    TypeDescriptor.GetConverter(type).CanConvertFrom(typeof(string));
Run Code Online (Sandbox Code Playgroud)

这将返回true

  • 所有原始类型
  • 所有枚举
  • string
  • decimal
  • DateTime
  • DateTimeOffset
  • TimeSpan
  • Uri
  • Guid
  • Nullable<> 上述任何类型
  • 实现了 nativeTypeConverter的许多其他类型(请参阅本部分的此处Derived

这种方法很有效,因为大多数框架TypeConverter本身就支持s,例如 XML 和 Json 序列化库,然后您可以使用相同的转换器在读取时解析值。