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的一个新实例,如果它是一个"复杂"类,则从一组源数据值填充其属性.

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

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

有没有快速简单的方法来判断我应该使用方法(A)还是方法(B)?此逻辑将在使用T作为类型参数的泛型方法中使用.

推荐答案

字符串可能是一个特例.

我想我会……

bool IsSimple(Type type)
{
    return type.IsPrimitive 
      || type.Equals(typeof(string));
}

Edit:

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

bool IsSimple(Type type)
{
  return type.IsPrimitive 
    || type.IsEnum
    || type.Equals(typeof(string))
    || type.Equals(typeof(decimal));
}

处理可为空的对应项也有点棘手.nullable本身就是一个 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));
}

测试:

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

Note to .NET Core

正如DucoJ在his answer中指出的那样,有些使用的方法在中的Type类中不可用.不再是网络核心了.

固定代码(我希望它能工作,我不能自己try .否则请 comments ):

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));
}

.net相关问答推荐

尽管有`disable`注释,但未 suppress Pylint语法错误

使用EFCore.BulkExtensions库方法BulkInertOrUpdate时区分插入和更新的记录

WinForm Task.Wait :为什么它会阻塞 UI?

使用 Task.WhenAll 但需要跟踪每个单独的 Task 的成功

移位比Java中的乘法和除法更快吗? .网?

是否可以模拟 .NET HttpWebResponse?

共享 AssemblyInfo 用于跨解决方案的统一版本控制

Winforms:Application.Exit vs Environment.Exit vs Form.Close

使用多个 MemoryCache 实例

注册 COM 互操作与使程序集 COM 可见

我应该从 .NET 中的 Exception 或 ApplicationException 派生自定义异常吗?

带有输入字段的消息框

DBNull 的意义何在?

自定义属性的构造函数何时运行?

从 OpenFileDialog 路径/文件名中提取路径

Linq to SQL - 返回前 n 行

为什么 C# 不推断我的泛型类型?

将月份 int 转换为月份名称

记录器包装器最佳实践

ConfigurationManager.AppSettings - 如何修改和保存?