2010-04-03 75 views
1

我在使用NHibernate和延迟加载时遇到私有setter的问题。比方说,我有一个类,看起来像这样:改变延迟加载的对象的私有变量

public class User 
{ 
    public virtual int Foo {get; private set;} 
    public virtual IList<User> Friends {get; set;} 

    public virtual void SetFirstFriendsFoo() 
    { 
     // This line works in a unit test but does nothing during a live run with 
     // a lazy-loaded Friends list 
     Friends(0).Foo = 1; 
    } 
} 

的SetFirstFriendsFoo呼叫完美的作品单元测试中(因为它应该因为objects of the same type can access each others private properties)。

但是,当使用惰性加载好友列表进行实时运行时,SetFirstFriendsFoo调用会以静默方式失败。我猜这是因为在运行时,Users(0).Foo对象不再是User类型,而是从User继承的代理类,因为Friends列表是延迟加载的。

我的问题是这样的:不应该生成运行时异常吗?如果你尝试访问另一个类的私有属性,你会得到编译时异常,但是当你遇到像这样的情况时,应用程序就会忽略你并继续沿着它前进。

注意:如果我将“私人设置”更改为“受保护的设置”,一切正常。

+0

你的意思是'朋友[0]。 Foo = 1;'而不是'Users(0).Foo = 1;'? – shahkalpesh 2010-04-03 13:33:59

+0

是的。修正了。对困惑感到抱歉。 – 2010-04-03 13:35:59

+0

因为私人方法不能代理和保护方法可以? – Paco 2010-04-03 13:43:25

回答

1

由于Paco指出只有虚拟方法/属性可以被代理,并且C#不允许虚拟私有成员。

您可以通过反射访问它,但我的第一个想法是,你应该尽量避免它。不过,如果你想去那里,你需要沿着这些路线的东西:

或者,你可以使用Fasterflect,做同样的是这样的:

Friends[ 0 ].SetPropertyValue("Foo", 1); 
+0

我忘了在我的属性前添加“虚拟”关键字。这是否会改变一切?它仍然是一个公共虚拟财产,但二传手是私人的。 – 2010-04-03 18:29:28

+0

据我所知,NHibernate使用Windsor来生成它的代理,所以看看文档,了解它到底支持什么。但为什么不只是让属性设置器保护而不是私人?无论如何,反射可以用来破坏封装,所以在这里寻求实用的解决方案可能是一个好主意。 – 2010-04-03 19:02:08