如何从IEnumerable <MyClass>中告诉IEnumerable <int>?

Chr*_*cht 1 .net c# generics

我有一个带IEnumerable<T>参数的方法.
T可以是一个内置的.NET类型一样intstring或自定义类是这样的:

class MyClass
{
    public string Foo{ get; set; }
    public int Bar{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我如何以编程方式识别是否T是内置类型之一?

我知道我可以这样做:

switch (typeof(T).Name.ToLower())
{
    case "int":          
    case "string":
    case "...":   // and so on...
        Console.WriteLine("It's a built-in type!");
        break;
    default:
        Console.WriteLine("It's a custom class!");
        break;
}
Run Code Online (Sandbox Code Playgroud)

......但必须有更短/更简单的方式,对吧?


编辑:

好的,非常感谢你们到目前为止的答案.
但我仍然不确定哪一个对我的情况最好.

我真正想做的是:
我正在编写一个库来转换IEnumerable<T>sADODB.Recordsets.
在每次转换开始时,我需要创建一个空的Recordset并向其添加字段.

如果T是自定义类,我必须遍历其属性并在Recordset中为每个属性T(使用属性的名称和类型)创建一个字段.

但是,如果T是自定义类,则循环遍历属性只能正常工作.
例如,它T是a string,我得到string(CharsLength)的属性,在这种情况下对我没用.

这意味着,只有当它的基本类型是不够的检查-我需要认识到的东西像DateTimeGUID为好,并有可能更大.
(我不得不承认,我没有注意到它DateTime不在内置类型列表中).

所以我想我真正想要的是:
告诉我是否T具有我可以循环的用户定义属性.
(无论它是否完全没有属性 int ,或者我不关心的属性 string 都有)
这有意义吗?

但是,我仍然不确定选择哪个答案.
driis'和Jon Skeet的答案都意味着我基本上必须列出很多类型(Jon的答案多于driis的答案).
目前,我倾向于选择Ron Sijm的答案(即使人们显然更喜欢其他答案),因为我认为只是检查"System."是做我想要的最短路的方式,即使它看起来不那么优雅. ..

dri*_*iis 6

这取决于您定义的"内置类型".在许多情况下,您可以查看类型是原始类型还是字符串.(因为字符串被认为是"内置",但它不是原始的).

if (typeof(T).IsPrimitive || typeof(T) == typeof(string))
    Console.WriteLine("It's a built-in type");
Run Code Online (Sandbox Code Playgroud)

如果您对这些原语(来自MSDN)感到满意,这是有效的:

基元类型是布尔,字节,SByte,Int16,UInt16,Int32,UInt32,Int64,UInt64,IntPtr,UIntPtr,Char,Double和Single.

请记住,typename int只是一个C#别名Int32.

编辑

为了确定可以直接用作记录集中的字段的类型,我可能首先查看IsPrimitive,然后使用ADO直接支持的其他"单值类型"的HashSet.类型灵机一动,包括轮番上涨Guid,Decimal,stringDateTime.我不认为有太多其他人,但我可能错了.

当然,直接驻留在System命名空间中的类型将是一种简单的方法,但是当您第一次通过a System.AppDomain或a 时,您将遇到麻烦System.Uri.基本上,如果你看一下System命名空间中的内容,绝大多数类型都不是你应该尝试放在单个字段中的东西.


Jon*_*eet 5

你确定是"内置式"很可能是特定的情境-你所列出内置到C#语言的类型,例如,但真的专门针对C#.它包括decimal(不是CLR原语类型),但不包括DateTime(其他语言可以明确支持).

所以,我只是使用HashSet<Type>你正确创建的:

private static readonly HashSet<Type> BuiltInTypes = new HashSet<Type>
{
    typeof(object), typeof(string), typeof(byte), typeof(sbyte),
    // etc
};

// Then:
if (BuiltInTypes.Contains(typeof(T)))
{
    Console.WriteLine("It's a built-in type!");
}
else
{
    Console.WriteLine("It's a custom class!");
}
Run Code Online (Sandbox Code Playgroud)