使用反射在C#中设置嵌套值
本文关键字:设置 嵌套 反射 | 更新日期: 2023-09-27 18:25:04
我有一个名为Article的类,它使用了另一个名称为ZoneStock的类。这个ZoneStock类有一个整数ID。
我想使用反射来修改它,但它不起作用。
我在Stack Overflow上找到了一些例子,但我没能成功。
public void Edit(int Id, string Key, string Value)
{
Article Article = Db.ArticleById(Id);
if (Key.Contains(".")) // in this case, Key = ZoneStock.Id
{
string[] Keys = Key.Split('.');
PropertyInfo Lvl1 = Article.GetType().GetProperty(Keys[0]); //Keys[0] = ZoneStock
Type T = Lvl1.PropertyType;
PropertyInfo Lvl2 = T.GetProperty(Keys[1]); //Keys[1] = Id
// Before this point it works, after ....
Lvl2.SetValue(Lvl1, Convert.ChangeType(Value, Lvl2.PropertyType), null);
Db.Update(ref Article);
}
else
{
// .......
}
Db.Save();
}
我找到了一个解决问题的方法,它是:
[HttpPost]
[ValidateAntiForgeryToken]
public string Edit(int Id, string Key, string Value)
{
Article Article = Db.ArticleById(Id);
if (Key.Contains(".")) //Property is a custom class
{
string[] Keys = Key.Split('.');
PropertyInfo prop = Article.GetType().GetProperty(Keys[0]);
Type type = prop.PropertyType;
object propInstance = Db.Object(type, Convert.ToInt32(Value)); // See the code of this method below
prop.SetValue(Article, propInstance);
Db.Update(ref Article);
}
else // Property is a simple type: string, int, double, dattime etc.
{
PropertyInfo prop = Article.GetType().GetProperty(Key);
prop.SetValue(Article, Convert.ChangeType(Value, prop.PropertyType), null);
Db.Update(ref Article);
}
Db.Save();
return Value;
}
public static object Object(Type type, int Id)
{
object Obj = Ctx.Set(type).Find(Id); //Ctx is may entityFramework Context
return Obj;
}
由于您将参数中的值直接分配给类型(Lvl1),而不是类型的实例,因此您似乎收到了类似"对象与目标类型不匹配"的错误消息。下面的代码应该可以直接赋值。
var newValue = Convert.ChangeType(Value, Lvl2.PropertyType);
Lvl2.SetValue(Lvl1.GetValue(Article), newValue);
根据评论更新基于新要求
如果级别1属性可能为null,则下面的代码将实例化该属性类型的实例。
// Article.ZoneStack is null
if (Lvl1.GetValue(Article) == null)
Lvl1.SetValue(Article, Activator.CreateInstance(Lvl1.PropertyType));
// Article.ZoneStack now has a new instance of ZoneStack assigned
var newValue = Convert.ChangeType(Value, Lvl2.PropertyType);
Lvl2.SetValue(Lvl1.GetValue(Article), newValue);
// Article.ZoneStack.Id == newValue