Знаете ли вы, Поля / Свойства объекта являются "простыми / примитивными" типами или другими объектами? - PullRequest
7 голосов
/ 19 декабря 2011

Я получил следующий код, который генерирует 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: Конечно, я надеваюне хочу выполнять строковую операцию над полем / свойством. Имя / Полное имя ... что-то вроде

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

было бы очень и очень неприятно ... и неточно)

Ответы [ 3 ]

5 голосов
/ 13 июля 2015

Это должно сделать это.

 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));
    }
5 голосов
/ 19 декабря 2011

Почему бы не использовать IsPrimitive класса Type?

XXX = field.FiledType.IsPrimitive

РЕДАКТИРОВАТЬ: Вам придется рассматривать string как особыйрегистр IsPrimitive не вернется true.

РЕДАКТИРОВАТЬ 2: Проблема, с которой вы столкнулись, состоит в том, что вы пытаетесь объединить два определения primitve , которыене совпадаютВ этом случае я вижу только два варианта:

  1. Сделайте так, чтобы оба определения совпадали, что, очевидно, вы не можете сделать, изменяя систему типов CLR, и, вероятно, не можете ни изменить структуру, которую вы

  2. Сделайте взломать , который "объединяет" оба определения.Я не вижу другого способа жесткого кодирования конкретных исключений, которые не соответствуют одному из двух определений типов primitve .

2 голосов
/ 19 декабря 2011

Вы можете использовать field.FieldType.IsPrimitive и prop.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 и т. д. Это действительно зависит от точно каковы ваши требования и точно что вы считаете примитивным типом.

...