我有一个 C# 代码,它会查看类上的每个公共属性并创建键和值的集合。关键只是一个访问属性的点符号变量;
我有以下型号
public class Home
{
public string Id { get; set; }
public string Summary { get; set; }
public Address Address { get; set; }
}
public class Address
{
public Street Street { get; set; }
public string CityName { get; set; }
public string StateName { get; set; }
}
public class Street
{
public string Number { get; set; }
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我有以下功能
public void GetPropertyKeyValue<T>(T obj, string prefix, List<ExtractedTerm> pairs)
{
if (pairs == null)
{
throw new ArgumentNullException(nameof(pairs));
}
// This works of the first object, but fails on the class properties
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
string key = property.Name;
if (!string.IsNullOrWhiteSpace(prefix))
{
key = $"{prefix}.{property.Name}";
}
Type type = property.PropertyType;
object value = property.GetValue(obj, null);
if (type.IsClass && !type.IsInterface && !type.IsEnum && !type.IsPrimitive && !type.IsString())
{
GetPropertyKeyValue(value, key, ref pairs);
continue;
}
pairs.Add(new ExtractedTerm(key, value, property.PropertyType));
}
}
Run Code Online (Sandbox Code Playgroud)
上面的方法是这样调用的
var home = new Home() {
Id = "100",
Summary = "Test",
Address = new Address() {
CityName = "Los Angeles"
}
}
var pairs = new List<ExtractedTerm>();
GetPropertyKeyValue(home, null, pairs);
Run Code Online (Sandbox Code Playgroud)
上面的代码在Home.Idand 和Home.Summaryand上完美地工作,Home.Address但是正弦Address是类类型的is 属性,因此该GetPropertyKeyValue方法被递归调用。当Address被传递的代码typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)不返回任何属性。但是,代码obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)返回预期的属性。但我真的不能算obj.GetType()为 obj 可能为空。正如您在上面的示例中注意到的,该Street属性为 null 并且obj.GetType()会引发异常。
为什么typeof()在某些情况下有效,但并非总是如此?即使obj为空,如何始终获得属性?
类型推断发生在编译时。
换句话说,由于value是静态类型object,
object value = property.GetValue(obj, null);
Run Code Online (Sandbox Code Playgroud)
以下行:
GetPropertyKeyValue(value, key, ref pairs);
Run Code Online (Sandbox Code Playgroud)
被编译为
GetPropertyKeyValue<object>(value, key, ref pairs);
Run Code Online (Sandbox Code Playgroud)
并typeof(object)产生......好吧......object类型。
如何解决这个问题?传入一个类型为 的参数,而不是使方法通用Type。这样,您只需传入property.PropertyType递归调用即可。我建议使用以下签名:
public void GetPropertyKeyValue<T>(T obj, string prefix, List<ExtractedTerm> pairs)
{
return GetPropertyKeyValue(typeof(T), obj, prefix, pairs);
}
private void GetPropertyKeyValue(Type type, object obj, string prefix, List<ExtractedTerm> pairs)
{
// contains your logic and recursively calls the non-generic version
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
48 次 |
| 最近记录: |