[英]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.