知道对象的字段/属性是"simple/primitive"类型还是其他对象?



我得到了以下生成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/等…):MyInt基本属性:MyString1个对象字段:SpeedGenerator11对象属性:gauevaluegenerator1

当我解析我的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)…)

(注:当然我不想做一个字符串操作字段/属性。名称/FullName…就像

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

会非常非常糟糕…和不准确)

应该可以了。

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

为什么不使用Type类中的IsPrimitive ?

XXX = field.FiledType.IsPrimitive

EDIT:您必须将string视为特殊情况,因为IsPrimitive将不返回true

EDIT 2:您遇到的问题是您正在尝试将两个不匹配的原始定义结合在一起。在这种情况下,我只能看到两个选项:

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

  2. 让一些hack"结合"这两个定义。对于不匹配基本类型的两种定义之一的特定异常,我认为没有其他方法可以硬编码。

您可以使用field.FieldType.IsPrimitiveprop.PropertyType.IsPrimitive,但如果您期望string, decimal等被视为原语,您将会失望。

为什么不创建你自己的类型集,你认为是基本类型,并检查它?

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.Object, TypeCode.DBNull等。它实际上取决于确切地您的需求是什么,以及确切地您认为什么是基本类型

最新更新