知道对象的字段/属性是“简单/原始”类型还是其他对象?

时间:2011-12-19 15:05:03

标签: c# properties field

我得到了以下生成DLL的代码(示例示例):

public class PluginClass
{
    private string _MyString;
    public string MyString
    {
        get { return _MyString; }
        set
        {
            _MyString = value;
            RaisePropertyChanged("MyString");
        }
    }

    public int MyInt;

    public SpeedGenerator SpeedGenerator1 = new SpeedGenerator();

    public GaugeValueGenerator GaugeValueGenerator1
    {
        get;
        set;
    }

    public PluginClass()
    {
        GaugeValueGenerator1 = new GaugeValueGenerator();
    }
}

如你所见,我有4个字段/属性。

1个原始字段(原语是int / string / bool / etcetc ...):MyInt 1个原始属性:MyString 1个对象字段:SpeedGenerator1 1个对象属性:GaugeValueGenerator1

当我解析我的DLL时,我得做一些函数中的代码:WriteProperty

var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
var props = type.GetProperties();

foreach (FieldInfo field in fields)
{
    WriteProperty(field.FieldType, field.Name, XXX);
}

foreach (PropertyInfo prop in props)
{
    WriteProperty(prop.PropertyType, prop.Name, XXX);
}

我的问题是关于XXX这是一个布尔值,表明我的字段/属性是否是“原始的”。因此,如果它是一个对象,则必须设置为false。 我摔倒了,就像我尝试了一切,但我无法解决它... 任何帮助都将非常感谢!

(我的想法是打电话

var props = propertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

并认为对于简单/原始类型它应该是空的!但是没有...例如在String上,这返回属性Chars(char [])和Length(int)...)

(nb:当然我不想对字段/ property.Name / FullName做一个字符串操作......类似

if ((propertyType.FullName).Contains("System."))

会非常非常糟糕......并且不准确)

3 个答案:

答案 0 :(得分:5)

为什么不使用Type类的IsPrimitive

XXX = field.FiledType.IsPrimitive

编辑:您必须将string视为一种特殊情况,因为IsPrimitive不会返回true

编辑2:您遇到的问题是您正在尝试将两个 primitve 定义结合在一起。因此,我只能看到两种选择:

  1. 使两个定义匹配,显然你无法改变CLR类型系统,也可能无法改变你正在使用的框架。

  2. 制作一些 hack ,使两个定义“结合”。我认为没有别的方法来硬编码与 primitve 类型的两个定义之一不匹配的特定异常。

答案 1 :(得分:5)

这应该这样做。

 public static bool IsPrimate(this object obj)
    {
        return new[]
        {
            typeof (Enum),
            typeof (String),
            typeof (Char),
            typeof (Guid),
            typeof (Boolean),
            typeof (Byte),
            typeof (Int16),
            typeof (Int32),
            typeof (Int64),
            typeof (Single),
            typeof (Double),
            typeof (Decimal),
            typeof (SByte),
            typeof (UInt16),
            typeof (UInt32),
            typeof (UInt64),
            typeof (DateTime),
            typeof (DateTimeOffset),
            typeof (TimeSpan),
        }.Any(oo => oo.IsInstanceOfType(obj));
    }

答案 2 :(得分:2)

您可以使用field.FieldType.IsPrimitiveprop.PropertyType.IsPrimitive,但如果您希望stringdecimal等被视为原语,那么您会感到失望。

为什么不创建自己的认为是原始类型的类型并检查它?

WriteProperty(f.FieldType, f.Name, yourPrimitives.Contains(f.FieldType));

// ...

WriteProperty(p.PropertyType, p.Name, yourPrimitives.Contains(p.PropertyType));

// ...

private static readonly HashSet<Type> yourPrimitives = new HashSet<Type>
    {
        typeof(int), typeof(string), typeof(decimal)    // etc
    };

另一种选择是使用GetTypeCode,然后检查结果不是TypeCode.ObjectTypeCode.DBNull等。这实际上取决于完全你的要求是,并且完全 认为是基本类型。