2010-04-03 65 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