我有一个问题。 假设我有一个Generic类,它可以具有其他类的泛型属性,甚至可以有其他类的列表。 如果我有像
这样的功能public void Read<T>() where T: class, new()
{
// Create an instance of our generic class
var model = new T();
var properties = typeof(T).GetProperties();
// Loop through the objects properties
for(var property in properties) {
// Set our value
SetPropertyValue(property, model, "test");
}
}
private void SetPropertyValue(PropertyInfo property, object model, string value) {
// Set our property value
property.SetValue(model, value, null);
}
如果我有这样的课程,那会有用:
public class Person
{
public string Name { get; set; }
}
我调用了 Read 方法,如下所示:
Read<Person>();
但如果我的人模型是这样的:
public class Person
{
public string Name { get; set; }
public Company Company { get; set; }
}
public class Company
{
public string Name { get; set; }
}
我试图再次调用 Read 方法,因为该属性拥有自己的属性列表,它会失败。 如果它也穿过它们会更好。有没有办法做到这一点?
答案 0 :(得分:1)
这answer可以提供帮助。 你应该以这样的结局结束:
if (t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) || ... )
SetPropertyValue(property, model, "test");
else
// You will have to recode this line,
// it's just to show you the idea how you can work around
SetPropertyValue(property, model, Read.MakeGeneric(property.Type)());
您还需要从Read方法返回模型变量。
条件取决于您要覆盖的类型,如果它与您的示例相似,则可以更改条件以仅匹配字符串,并添加对else的检查以检查作为对象的属性。 / p>
答案 1 :(得分:1)
如果属性值是字符串,则可以直接设置该属性值,否则可以返回类似于Read
的方法的值,该方法将Type
作为参数来创建模型并递归填充其属性
public void Read<T>() where T : class, new()
{
// Create an instance of our generic class
var model = new T();
var properties = typeof(T).GetProperties();
// Loop through the objects properties
foreach(var property in properties)
{
// Set our value
SetPropertyValue(property, model, "test");
}
}
private void SetPropertyValue(PropertyInfo property, object model, string value)
{
if (property.PropertyType == typeof(string))
{
// Set our property value
property.SetValue(model, value, null);
}
else
{
var submodel = Read(property.PropertyType);
property.SetValue(model, submodel, null);
}
}
private object Read(Type type)
{
if (!IsTypeSupported(type))
{
throw new ArgumentException();
}
var model = type.GetConstructor(new Type[0]).Invoke(new object[0]);
var properties = type.GetProperties();
foreach (var property in properties)
{
SetPropertyValue(property, model, "test");
}
return model;
}
private bool IsTypeSupported(Type type)
{
return type.IsClass && type.GetConstructor(new Type[0]) != null;
}