C#: как определить, является ли объект пользовательским классом или собственным типом /.NET-классом?

у меня есть этот класс

public class MyViewModel {
  public MyClass Thing { get; set; }
  public int Id { get { return Thing.Id; } }
  public string Name { get { return Thing.Name; } }
}

Я заметил, когда я привязываю его к ASP.NET GridView, он автоматически опускает Thing, и по уважительной причине (т. е. потому что в противном случае он будет показывать только бессмысленное "MyNamespace".Класса MyClass" во всех строках)

Я пытаюсь сделать подобную вещь в этом методе.

public static string ConvertToCsv<T>(IEnumerable<T> items)
{
  foreach (T item in items)
  {
    if(item is not a native/.NET class) // <-- How do you do this?
      continue;
    else // If it is a string/int/bool/DateTime or something meaningful
    {
      ...
    }
  }
}

3 ответов


не уверен в производительности, но вы можете использовать что-то вроде

if(item.GetType().Namespace.StartsWith("System")) 
{
   // do stuff
}

или фильтр перед зацикливание

public static string ConvertToCsv<T>(IEnumerable<T> items)
{
    foreach (T item in items.Where(i => i.GetType().Namespace.StartsWith("System")))
    {

    }
}

Edit: после быстрого теста метод выше имеет некоторые недостатки, Если ваш объект nullable (MyViewModel?) он будет подобран в этом чеке (System.Nullable<MyViewModel>).

так что, возможно, вы могли бы использовать:

public static string ConvertToCsv<T>(IEnumerable<T> items)
{
    foreach (T item in items.Where(i => i.GetType().Module.ScopeName.Equals("CommonLanguageRuntimeLibrary")))
    {

    }
}

другой редактировать: Кажется, есть некоторые проблемы с последним методом, но этот ниже, безусловно, самый быстрый и надежный, мы просто создаем список системы.Объекты из сборки и проверьте, находится ли объект элемента в этом списке.

private List<Type> _systemTypes;
public List<Type> SystemTypes
{
    get
    {
        if (_systemTypes == null)
        {
            _systemTypes = Assembly.GetExecutingAssembly().GetType().Module.Assembly.GetExportedTypes().ToList();
        }
        return _systemTypes;
    }
}

public static string ConvertToCsv<T>(IEnumerable<T> items)
{
    foreach (T item in items.Where(i => SystemTypes.Contains(i.GetType())))
    {
         // is system type
    }
}

вам придется искать его в предопределенной хэш-таблице или словаре ... скажем, перечисляя все сборки, входящие в состав пакета SDK .NET Framework, и сохраняя полное имя в словаре.


Я знаю, что это старый, но я думаю, что вы ищете способ.

Type type = result.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
    string prs = property.GetMethod.ToString();
    if(!prs.StartsWith("System"))
    {
        //IS CLass
    } else {
       Console.WriteLine(property.Name + ":::" + property.Value);
    }
}