使用反射在C#中设置嵌套值

使用反射在C#中设置嵌套值,c#,C#,我有一个名为Article的类,它使用另一个名为ZoneStock的类。 此ZoneStock类具有整数ID 我想使用反射来修改它,但它不起作用 我找到了一些关于堆栈溢出的示例,但我没有成功地使其工作 public void Edit(int Id, string Key, string Value) { Article Article = Db.ArticleById(Id); if (Key.Contains(".")) // in this case,

我有一个名为Article的类,它使用另一个名为ZoneStock的类。 此ZoneStock类具有整数ID

我想使用反射来修改它,但它不起作用

我找到了一些关于堆栈溢出的示例,但我没有成功地使其工作

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();

    }

看起来您收到了类似“对象与目标类型不匹配”的错误消息,因为您将参数中的值直接分配给类型(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

我找到了解决问题的方法,如下:

[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;
    }

你说的“它不起作用”和“我没能使它起作用”是什么意思?请解释什么不起作用。你有错误吗?它会崩溃吗?数据库是否未按预期更新?该代码是否无意中向教皇发送了一条短信?@pstrjds很确定教皇会将其作为梵蒂冈的非主题关闭。文章似乎不好。你应该更改它。谢谢你的回答。是的,你说得对。不幸的是,Lvl1实例不存在,因为这是我第一次向它赋值。Lvl1.GetValue(Article)返回null,而您的解决方案返回“一个非静态方法需要一个目标”。您问题中的措辞使文章的ZoneStack看起来已经存在(也是因为您正在执行Db.Update)。如果您正在分配一个新的ZoneStack,希望您的Db.Update能够处理插入/更新(如果它还不存在)。我更新了答案,包括实例化1级属性。谢谢。经过昨天的一些测试,我发现这个含有活化剂的溶液。它工作得很好,但我仍然有一个问题。我稍后会描述它。谢谢