2013-10-11 42 views
0

我遇到了這種情況,我可以在外面修改班級的私人成員。這裏是我的課:能夠修改課外私人會員嗎?

public class MyClass 
{ 
    private List<string> _myClassMember = null; 

    public MyClass() 
    { 
     _myClassMember = new List<string>(); 
    } 

    public List<string> GetClassMembers() 
    { 
     return _myClassMember; 
    } 

    public void PrintMembers() 
    { 
     Console.WriteLine("No of items in member {0}", _myClassMember.Count.ToString()); 
    } 
} 

這是它是如何被稱爲:

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyClass cls = new MyClass(); 
     cls.PrintMembers(); 
     IList<string> lst = cls.GetClassMembers(); 
     lst.Add("Item1"); 
     lst.Add("Item2"); 
     cls.PrintMembers(); 
    } 
} 

它打印如下:

No of items in member 0 
No of items in member 2 

的是,正確的能夠外面更新私有成員?

+0

如果您希望您的列表不可變,即調用GetClassMembers()的代碼將無法修改它,您可以從您的公共方法返回_myClassMember..AsReadOnlyCollection()。 –

+0

將'GetClassMembers()'從'return _myClassMember;'更改爲'返回新的ReadOnlyCollection (_myClassMember);'相應地更新簽名。請參閱http://msdn.microsoft.com/en-us/library/ms132474.aspx。 – Brian

回答

6

是。這只是私人的參考。如果你分享那個參考。然後外部代碼可以自由修改其內容。

如果您不希望外部代碼修改內容,請改爲使用不可變的集合類。

雖然您可以修改myClassMember所引用列表的內容,但您無法從課程外做的是更改myClassMember指向的列表。

2

這是C#中的預期行爲。列表是所謂的引用類型,這意味着當你從一個函數返回它時,你實際上會返回一個對你的類中的對象的引用。這可以讓你修改它。

這裏是解釋引用類型和值類型之間的差異的鏈接:

Click here

這裏是你可以做些什麼來防止修改一個例子:

public class MyClass 
{ 
    private List<string> _myClassMember = null; 

    public MyClass() 
    { 
     _myClassMember = new List<string>(); 
    } 

    public IReadOnlyList<string> GetClassMembers() 
    { 
     return _myClassMember.AsReadOnly(); 
    } 

    public void PrintMembers() 
    { 
     Console.WriteLine("No of items in member {0}", _myClassMember.Count.ToString()); 
    } 
} 
0

我認爲這是不正確的。私有成員的概念是,你不能在某種程度上直接訪問諸如

cls._myClassMember.Add("Item1"); 

但因爲你在呼喚

cls.GetClassMembers(); 

它返回類的成員,那麼你可以做修改它。

0

是的,這是完全合法的。如果您想有類的外部訪問私有變量,你通常使用一個屬性(get /集):

private List<string> _myClassMember = null; 

public List<string> MyClassMember 
{ 
    get { return _myClassMember; } 
    set { _myClassMember = value; } 
} 

刪除屬性的set部分,如果你希望別人能夠添加/刪除項目,但實際上並沒有將新列表(或空值)分配給_myClassMember

6

這是最近這個問題第二次出現。

想想這個的正確方法是數據不是私有的。 名稱是私人的東西。如果您選擇以某種方式在課程外共享數據,那不會破壞封裝。實際上私人的東西是名稱_myClassMember,它只是指在類內的代碼中的字段。

詳情請參閱

Interface behavior is dfferent in VB.Net