如何在C#中获取对象的所有简单属性

时间:2013-11-26 14:28:03

标签: c# .net reflection

我想知道如何获得所有类型的对象,而不是指向另一个类。

e.g。这将包括string,int,datetime等      但不包括指向集合或其他自定义类的指针

我有以下内容,但它似乎没有返回字符串:

PropertyInfo[] properties = typeOfObject.GetProperties();

foreach (PropertyInfo property in properties.Where(p => !p.PropertyType.IsClass))
{
}

正如Leri所说 - 我打算拿一个对象的原始副本,没有集合/类等。所以它必须包含所有原始类型,字符串,日期时间和其他任何存在的类型。

4 个答案:

答案 0 :(得分:7)

因为String是一个类,而不是Int32Double等结构

如果您想要的不是类,而是包含字符串,请指定!

foreach (PropertyInfo property in 
         properties.Where(p => !p.PropertyType.IsClass 
                                  || p.PropertyType == typeof(String)))
{
}

答案 1 :(得分:2)

您的代码也会为您提供所有结构,这些结构本身可以包含对集合等的引用,因此它不会这样做。

你最好的选择可能是要求IsPrimitive(它给你int,short等),并添加你想要的任何其他已知类型,如string,DateTime等。

答案 2 :(得分:1)

我决定在这里混合使用几种解决方案。

首先,由于结构问题等问题,我决定保留Leri提到的允许类型列表。

其次,根据Luaan的评论,我已经写了一个处理这些问题的方法。

所以解决方案如下:

迭代属性的代码

foreach (PropertyInfo property in properties)
{
 if (this.IsTypeASimpleType(property.PropertyType) &&
     property.CanWrite)
 {
 }
}

然后检查类型是否正确的代码

    private bool IsTypeASimpleType(Type typeToCheck)
    {
        var typeCode = Type.GetTypeCode(this.GetUnderlyingType(typeToCheck));

        switch (typeCode)
        {
            case TypeCode.Boolean:
            case TypeCode.Byte:
            case TypeCode.Char:
            case TypeCode.DateTime:
            case TypeCode.Decimal:
            case TypeCode.Double:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
            case TypeCode.SByte:
            case TypeCode.Single:
            case TypeCode.String:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
                return true;
            default:
                return false;
        }
    }

处理nullables的代码

    private Type GetUnderlyingType(Type typeToCheck)
    {
        if (typeToCheck.IsGenericType &&
            typeToCheck.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            return Nullable.GetUnderlyingType(typeToCheck);
        }
        else
        {
            return typeToCheck;
        }
    }

现在,switch语句可能已更改为允许类型列表,但最终游戏将是相同的。

答案 3 :(得分:0)

好的,有了你提炼的问题,更好的答案是:如果你能够在一个变量上调用GetType(),那么它将返回一个对象,你可以反思该对象以获得底层类型。您还可以询问该类型是否是某个其他现有类型的实例,这有助于确定运行时类型的安全性(“如果我将此实体视为Cat类型的对象,我的代码会抛出异常吗?”

所以我认为你想要做的是调用GetType()。然后,您可以使用返回的类型对象执行许多操作。其中之一是测试完全匹配,例如这样:“if(x.GetType()。Equals(typeof(int)))....

实际上有几种方法可以做到并且所有这些方法都有效。我刚刚做的完全匹配非常严格。但请注意,您可以使用typeof(int)来获取将成为int类型的真实基础类型表示的Type对象,即使int是C#中的基类型,因此int类型的东西不是对象 - - 在运行时它由值表示,而不是由引用表示。这是有效的,因为在编译时解析了typeof()。

所以我认为,出于你的目的,这可能是你需要做的。