Как определить, является ли тип объекта встроенным системным типом

Я пишу простой конвертер List<t> в CSV. Мой конвертер проверяет все t в списке и захватывает все общедоступные свойства и помещает их в CSV.

Мой код отлично работает (как и предполагалось), когда вы будете использовать простой класс с несколькими свойствами.

Я хотел бы получить конвертер List<t> в CSV, чтобы также принять типы системы, такие как String и Integer. С этими типами систем я не хочу получать свои общедоступные свойства (такие как Length, Chars и т.д.). Таким образом, я хотел бы проверить, является ли объект типом системы. По типу системы я имею в виду один из встроенных типов .Net, таких как string, int32, double и т.д.

Используя GetType(), я могу узнать следующее:

string myName = "Joe Doe";

bool isPrimitive = myName.GetType().IsPrimitive; // False
bool isSealed = myName.GetType().IsSealed; // True 
// From memory all of the System types are sealed.
bool isValueType = myName.GetType().IsValueType; // False

// LinqPad users: isPrimitive.Dump();isSealed.Dump();isValueType.Dump();

Как я могу найти, если переменная myName - это встроенный тип системы? (предполагая, что мы не знаем его строку)

Ответ 1

myName.GetType().Namespace
Это вернет System, если это встроенный тип.

Ответ 2

Вот несколько из нескольких возможностей:

  • myName.GetType().Namespace == "System"
  • myName.GetType().Namespace.StartsWith("System")
  • myName.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"

Ответ 3

Если вы не можете точно определить, что такое "встроенный системный тип", тогда кажется вероятным, что вы не будете знать, какие типы находятся в любом ответе. Более вероятно, что вы хотите сделать, это просто список типов, с которыми вы не хотите этого делать. Имейте метод IsSimpleType, который просто проверяет различные типы.

Другая вещь, которую вы можете искать, - это примитивные типы. Если да, посмотрите:

Type.IsPrimitive(http://msdn.microsoft.com/en-us/library/system.type.isprimitive.aspx)

Примитивные типы являются булевыми, байтовыми, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single.

Это не включает строку, но вы можете добавить это вручную...

См. также Как проверить, является ли тип примитивным

Ответ 4

Методы, основанные на пространстве имен, потенциально могут вызывать конфликты.

Есть еще один надежный и простой способ:

static bool IsSystemType(this Type type) => type.Assembly == typeof(object).Assembly;

Или чуть более оптимально, кэшируя сборку системы:

static readonly Assembly SystemAssembly = typeof(object).Assembly;

static bool IsSystemType(this Type type) => type.Assembly == SystemAssembly;

Ответ 5

Я думаю, что это лучшая возможность:

private static bool IsBulitinType(Type type)
{
    return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object);
}

Ответ 6

Я строил что-то рефлексивно и обнаружил, что свойство IsSecurityCritical, похоже, работает для этой цели; однако это было связано только с тем, что уровень доверия для моей сборки был недостаточно высоким, чтобы перевернуть этот бит.

Немного смеяться; к счастью, я нашел этот вопрос и будет соответствующим образом корректироваться.

Примечание. Свойство IsSecurityCritical существует только в том случае, если .NetFramework > 4

Я, скорее всего, поеду; следующее из предыдущего ответа.

myName.GetType(). Module.ScopeName == "CommonLanguageRuntimeLibrary"

Но с помощью нескольких настроек; например, сделать его методом расширения на Type и использовать const для CommonLanguageRuntimeLibrary