我使用反射来更新已对其进行更新并保存到mongodb的对象

    private void updateSelf(MongoDoc newDoc)
    {
        Type type = this.GetType();
        foreach (var i in type.GetProperties())
        {
            if (i.GetCustomAttributes(false).Any(x => x is MongoDB.Bson.Serialization.Attributes.BsonIgnoreAttribute)) continue;
            Object oldValue = i.GetValue(this, null);
            Object newValue = i.GetValue(newDoc, null);
            if (!Object.Equals(oldValue, newValue) && !((oldValue == null) && (newValue == null)))
            {
                i.SetValue(this, newValue, null);
            }
        }
    }


这在大多数情况下都有效,但是i.SetValue(this, newValue, null);在尝试更新此属性时会引发异常:

public uint Revision { get; private set; }


这正在尝试更新Product类型的对象,该对象是MongoDoc的派生类型,其中包含属性public uint Revision { get; private set; }导致异常Property set Method not found,我不确定是什么原因造成的,因为它适用于所有我的其他属性,仅此一项引发异常。任何帮助表示赞赏

更新:

我试过下面的答案:

i.SetValue(this, newValue, System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, null, null, null);


但不幸的是,结果完全相同,它仍然在Revision属性上引发异常。

更新:

例外:

System.ArgumentException was unhandled
  Message=Property set method not found.
  Source=mscorlib
  StackTrace:
       at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
       at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
       at Flo.Client.Docs.MongoDoc.updateSelf(MongoDoc newDoc) in F:\Flo\Flo.Client\Docs\MongoDoc.cs:line 162
       at Flo.Client.Docs.MongoDoc.UpdateToMongo(MongoDoc newDoc) in F:\Flo\Flo.Client\Docs\MongoDoc.cs:line 120
       at Flo.Client.Docs.Product.EditProduct(String Name, Nullable`1 State) in F:\Flo\Flo.Client\Docs\Product.cs:line 89
       at Flo.Client.Program.Main() in F:\Flo\Flo.Client\Program.cs:line 26
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

最佳答案

我对此进行了修复,这要归功于Dylan Meador向我提出的另一个问题,该问题使我有足够的能力来获得解决方案:

    private void updateSelf(MongoDoc newDoc, Type type)
    {
        foreach (var i in type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public))
        {
            if (i.GetCustomAttributes(false).Any(x => x is MongoDB.Bson.Serialization.Attributes.BsonIgnoreAttribute)) continue;
            Object oldValue = i.GetValue(this, null);
            Object newValue = i.GetValue(newDoc, null);
            if (!Object.Equals(oldValue, newValue) && !((oldValue == null) && (newValue == null)))
            {
                i.SetValue(this, newValue, null);
            }
        }
        Type baseType = type.BaseType;
        if (baseType != null)
        {
            this.updateSelf(newDoc, baseType);
        }
    }


看起来需要将Type显式设置为基类类型,才能将set访问器用于该特定属性。

关于c# - C#反射SetValue()找不到集合访问器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12431869/

10-09 13:35