简体   繁体   English

使用反射我们如何判断 class 属性是否为可空集合并获取其数据类型?

[英]Using reflection how can we tell if a class property is a nullable collection and get its data type?

I have no problems with properties that are non-nullable collections but everything changes when the property is a nullable collection...我对不可为空的 collections 的属性没有任何问题,但是当属性是可以为空的集合时,一切都会改变......

Given a class with nullable collection properties (int?[], long?[], List<Nullable>, ...)给定具有可为空集合属性的 class (int?[], long?[], List<Nullable>, ...)

public class SomeClass
{
    public int?[] PropertyX { get; set; }
    public long?[] PropertyY { get; set; }
    public float?[] PropertyZ { get; set; }
    public List<decimal?> PropertyList { get; set; }
    public string Name { get; set; }
} 

How can I tell if the property is a nullable collection ?如何判断该属性是否为可为空的集合
Does the nullable collection have any actual values ?可空集合是否有任何实际值
Lastly what is the nullable collections data type ?最后,什么是可为空的 collections 数据类型

public class SomeOtherClass
{
    public string Discover(SomeClass someClass)
    {
        var sb = new StringBuilder();
        foreach (var propertyInfo in someClass.GetType().GetProperties())
        {
            var propValue = propertyInfo.GetValue(someClass, new object[] { });
            if (propValue.IsNullableCollection() && propValue.HasValue())
            {
                sb.AppendFormat("{0} data type is {1}", propValue.GetDataType());
            }
        }
        return sb.ToString();
    }
}

Example:例子:

void Main
{
  var sc = new SomeClass() 
  {
    PropertyX = new int?[2]{50,10}
  };
  var output = new SomeOtherClass().Discover(sc); 
  
  //Display Output ...
}

"PropertyX has values and data type is int." “PropertyX 有值,数据类型是 int。”

I've written a method that should give you all the tools you need for your task:我编写了一个方法,它应该为您提供完成任务所需的所有工具:

public static void Discover(Type mainType)
{
    foreach (var pi in mainType.GetProperties())
    {
        var t = pi.PropertyType;
        if (t.IsArray)
        {
            (var isNullable, var innerT) = ExamineForNullable(t.GetElementType());
            Console.WriteLine($"{pi.Name} data type is an array of {innerT} (nullable: {isNullable})");
        }
        else if (t.GetInterface(nameof(ICollection)) != null)
        {
            //TODO this is true for dictionaries too!
            if (t.IsGenericType)
            {
                (var isNullable, var innerT) = ExamineForNullable(t.GetGenericArguments()[0]);
                Console.WriteLine($"{pi.Name} data type is collection of {innerT} (nullable: {isNullable})");
            }
            else
            {
                //TODO
            }

        }
        else
        {
            Console.WriteLine($"{pi.Name} data type is {t}");
        }
    }
}

static (bool nullable, Type type) ExamineForNullable(Type t)
    => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)
            ? (true, Nullable.GetUnderlyingType(t))
            : (false, t);

Let's run it with the following class, which is a modified version of you example class:让我们使用以下 class 运行它,这是示例 class 的修改版本:

public class SomeClass
{
    public int?[] PropertyX { get; set; }

    public List<decimal?> List1 { get; set; }

    public List<decimal> List2 { get; set; }

    public string Name { get; set; }

    public Dictionary<string, decimal?> Dictionary { get; set; }
}

(...) 

Discover(typeof(SomeClass));

Please not that you don't need an object of the class to examine the types: Discover( new SomeClass()) vs Discover(typeof(SomeClass) .请注意,您不需要 class 的 object 来检查类型: Discover( new SomeClass())Discover(typeof(SomeClass)

The output is: output 是:

PropertyX data type is an array of System.Int32 (nullable: True)
List1 data type is collection of System.Decimal (nullable: True)
List2 data type is collection of System.Decimal (nullable: False)
Name data type is System.String
Dictionary data type is collection of System.String (nullable: False)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用反射的子类的类属性名称及其数据类型 - Class property name and its data type for sub class using Reflection 如何通过反射获得可空类型的值 - How to get value of a Nullable Type via reflection 如何通过反射获取类中属性的“类类型”? - how to get the “class type” of a property in a class through reflection? 使用反射时,C#确定Nullable属性DateTime类型 - C# determine a Nullable property DateTime type when using reflection 如果属性是反射中的集合,如何知道它的类型? - How to know the Type of a Property if it is collection in Reflection? 如何通过反射C#获取类中属性的数据类型 - How do I get data type of property in a class through Reflection C# 泛型 class 使用泛型类型的可空属性 - generic class using nullable property of generic type 如何提示 C# 8.0 可为空引用系统使用反射初始化属性 - How can I hint the C# 8.0 nullable reference system that a property is initalized using reflection 我可以在不使用反射的情况下获取 class 中的字段或属性的 PropertyInfo 吗? - Can I get PropertyInfo for a field or property in a class without using reflection? 如何使用反射获取类的所有静态属性及其值 - How to get all static properties and its values of a class using reflection
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM