Подтвердить что ты не робот

Как узнать, является ли тип "простым"? т.е. имеет единственное значение

typeof(string).IsPrimitive == false
typeof(int).IsPrimitive == true
typeof(MyClass).IsClass == true
typeof(string).IsClass == true
typeof(string).IsByRef == false
typeof(MyClass).IsByRef == true // correction: should be false (see comments below)

У меня есть метод, который создает экземпляр нового экземпляра T и, если он является "сложным" классом, заполняет его свойства из набора значений исходных данных.

(a) Если T - простой тип (например, строка или int или что-то еще подобное), необходимо выполнить быстрое преобразование из исходных данных в T.

(b) Если T - класс (но не что-то простое, как строка), то я буду использовать Activator.CreateInstance и немного отразить, чтобы заполнить поля.

Есть ли простой и простой способ сказать, следует ли мне использовать метод (a) или метод (b)? Эта логика будет использоваться внутри общего метода с T как аргументом типа.

4b9b3361

Ответ 1

Строка, вероятно, является особым случаем.

Я думаю, что буду делать.....

bool IsSimple(Type type)
{
    return type.IsPrimitive 
      || type.Equals(typeof(string)));
}

Edit:

Иногда вам нужно прикрывать еще несколько случаев, например перечисления и десятичные числа. Перечисления - это особый тип типа в С#. Десятичные числа - это структуры, как и любые другие. Проблема с структурами заключается в том, что они могут быть сложными, они могут быть определенными пользователем типами, они могут быть просто числом. Таким образом, у вас нет другого шанса, чем знать, что они должны различать.

bool IsSimple(Type type)
{
  return type.IsPrimitive 
    || type.IsEnum
    || type.Equals(typeof(string))
    || type.Equals(typeof(decimal));
}

Обработка совпадающих с нулями эквивалентов также немного сложна. Сама с нулевым значением является структурой.

bool IsSimple(Type type)
{
  if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
  {
    // nullable type, check if the nested type is simple.
    return IsSimple(type.GetGenericArguments()[0]);
  }
  return type.IsPrimitive 
    || type.IsEnum
    || type.Equals(typeof(string))
    || type.Equals(typeof(decimal));
}

Тест:

Assert.IsTrue(IsSimple(typeof(string)));
Assert.IsTrue(IsSimple(typeof(int)));
Assert.IsTrue(IsSimple(typeof(decimal)));
Assert.IsTrue(IsSimple(typeof(float)));
Assert.IsTrue(IsSimple(typeof(StringComparison)));  // enum
Assert.IsTrue(IsSimple(typeof(int?)));
Assert.IsTrue(IsSimple(typeof(decimal?)));
Assert.IsTrue(IsSimple(typeof(StringComparison?)));
Assert.IsFalse(IsSimple(typeof(object)));
Assert.IsFalse(IsSimple(typeof(Point)));  // struct in System.Drawing
Assert.IsFalse(IsSimple(typeof(Point?)));
Assert.IsFalse(IsSimple(typeof(StringBuilder))); // reference type

Ответ 2

В дополнение к Stefan Steinegger ответ: В .NET Core.IsPrimitive и т.д. Больше не являются членами Type, они теперь являются членами TypeInfo. Поэтому его решение станет следующим:

bool IsSimple(TypeInfo type)
{
    if (type.IsGenericType && type.GetGenericTypeDefinition() ==     typeof(Nullable<>))
    {
        // nullable type, check if the nested type is simple.
        return IsSimple((type.GetGenericArguments()[0]).GetTypeInfo());
    }
    return type.IsPrimitive
      || type.IsEnum
      || type.Equals(typeof(string))
      || type.Equals(typeof(decimal));
}

Ответ 3

Существует более общий тип, чем примитив, ValueType включает в себя гораздо больше, чем примитивный, например перечисления, десятичные и другие подобные вещи ValueType. Ниже приведена функция, которую я написал для определения сложных типов, которые могут соответствовать вашим потребностям.

    public static bool IsComplex(Type typeIn)
    {
        if (typeIn.IsSubclassOf(typeof(System.ValueType)) || typeIn.Equals(typeof(string))) //|| typeIn.IsPrimitive
            return false;
        else
            return true;

    }

Ответ 4

Извините, что воскресил действительно старый поток, но поскольку он по-прежнему высоко ценит веб-поиск в Google, вы хотите получить более прямое и эффективное решение:

if(System.Type.GetTypeCode(typeof(int)) == TypeCode.Object) {
    // Do what you will...
}

Ответ 5

Возможно, это не имеет значения, но похоже, что вы оставляете несколько случаев:

  • Сложные типы, имеющие преобразования
  • Типы значений, у которых нет конструктора без параметров. Пример ниже:

Есть, вероятно, больше, но я думаю, что вы разбиваете проблемное пространство чрезмерно ограничительным образом.

 public class Person {
    private string _name;
    private int _age;
    public Person(string name, int age) {_name = name; _age = age;}
    // Remainder of value implementation
 }

Ответ 6

Строки не примитивы, если я правильно помню. хотя для него есть ключевое слово, строка - это объект. Ваш вызов IsPrimitive точно скажет вам, является ли что-то примитивным.