2013-11-26 9 views
2

Мне было интересно, как бы я хотел получить все типы объектов, которые не указывают на другой класс.Как получить все простые свойства объекта в C#

например. это будет включать в себя строку, INT, DATETIME и т.д. , но не будет включать в себя указатель на коллекции или другие пользовательские классы

У меня есть следующие, но это, кажется, не возвращать строки:

PropertyInfo[] properties = typeOfObject.GetProperties(); 

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

Как спрошенный Лэри - я планирую взять примитивную копию объекта, без NO collection/classes и т. д. SO должен содержать все примитивные типы, строки, дату и время и любые другие.

+0

Зачем вам это нужно? Похоже, вы делаете какое-то сопоставление. Добавление большего контекста позволит нам дать более точные ответы. – Leri

+0

Это не дубликат. Я знаю, как получить свойства, но я не знал, как можно получить конкретные свойства по моему вопросу. Leri - я обновил свой вопрос внизу – eyeballpaul

+0

Возможный дубликат [Проверить, не объект ли объект-тип?] (Http://stackoverflow.com/questions/13128028/check-if-an-object-is-non- basetype) – Servy

ответ

5

Поскольку String является классом, а не структура, как Int32 и Double т.д.

Если вы хотите, все, что это не класс, но в том числе строки, просто указать, что!

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

|| p.PropertyType == typeof (DateTime) –

+0

Какие другие встроенные типы будут отсутствовать из этой строки, кроме строки? Эмиль также упоминает DateTime, есть ли другие? – eyeballpaul

+1

Комментарий Эмиля неверен, DateTime не является классом, поэтому для этого вам не нужно иметь исключение. Однако, как я сказал в своем ответе, у вас может быть структура (которая не является классом и пройдет тест), которая ссылается на другие классы. – Luaan

2

Ваш код также даст вам все, что Структуры могут сами по себе содержат ссылки на коллекции и т.д., так что он не будет делать.

Лучше всего, вероятно, просить IsPrimitive (что дает вам ИНТ, короткое и т.д.), а также добавить любые другие известные типы вы хотите, такие как строки, DateTime и т.д.

+0

О, хорошо, я никогда не думал о Structs. В этом случае у меня фактически не будет никаких структур, но для будущей проверки лучше всего позаботиться о них только сейчас. Итак, кроме строки, datetime, что бы не было включено в «IsPrimitive»? А как насчет нулевых типов? – eyeballpaul

+0

MSDN говорит: «Примитивные типы: Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single». Неудачные типы будут сложными, в основном вам нужно получить определение общего типа - 'p.PropertyType.GetGenericTypeDefinition() == typeof (Nullable <>)'. Тем не менее, nullable может содержать любой тип значения, поэтому вам нужно проверить свой список разрешенных типов в отношении параметра типа. – Luaan

0

Хорошо, с утонченным вопросом , лучший ответ таков: если вы можете вызвать GetType() для переменной, которая возвращает объект, и вы можете подумать об этом объекте, чтобы получить базовый тип. Вы также можете спросить, является ли тип экземпляром какого-либо другого существующего типа, который может быть полезен для определения безопасности типа времени выполнения («будет ли мой код выдавать исключение, если я рассматриваю этот объект как объект типа Cat?»)

Итак, я думаю, что вы хотите сделать это, чтобы вызвать GetType(). Тогда есть много вещей, которые вы можете сделать с возвращаемым типом. Один из них - это проверка для точного соответствия, например, следующим образом: «if (x.GetType()). Equals (typeof (int))) ....

На самом деле существует несколько способов сделать это и но все же обратите внимание, что вы можете использовать typeof (int), чтобы получить объект Type, который будет истинным базовым типом представления для типа int, хотя int является базой тип в C# и, следовательно, что-то типа int не является объектом - во время выполнения оно представлено значением, а не ссылкой. Это работает, потому что typeof() разрешается во время компиляции.

Так что я думаю, что для ваших целей это может быть то, что вам нужно.

+0

Я обновил свой вопрос, почему я пытаюсь это сделать – eyeballpaul

0

Я решил сделать смесь пара решений здесь.

Во-первых, из-за проблем с structs и т. Д. Я решил сохранить список разрешенных типов, упомянутых 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 мог быть изменен на список разрешенных типов, но конечная игра будет одинаковой.

Смежные вопросы