簡體   English   中英

C#,使公共成員的方法變得私密

[英]C#, making public members their methods private

我是以下課程:

    public class Humptydump
    {
        public Humptydump()
        { }

        public Rectangle Rectangle { public get; private set; }

    }

在這個類中,Rectangle類來自system.drawing,
我怎么做它所以人們無法訪問矩形的方法,但可以得到矩形本身?

在你的情況下,它將“正常工作”。

由於Rectangle是一個struct ,因此您的屬性將返回Rectangle副本 因此,任何人都不可能直接修改Rectangle ,除非您公開允許這樣做的方法。

話雖這么說,一般來說,提供對類型的訪問是不可能的,而不提供對類型上定義的方法的訪問。 方法與類型一致。 在這些情況下,唯一的選擇是創建一個新類型,在沒有您希望公開的數據或方法的情況下公開您選擇的數據,並提供對它的訪問。

如果矩形不是結構,那么可能會導出它並隱藏這些方法:

public class DerivedClass : BaseClass
{

    new private SomeReturnType SomeMethodFromBaseClasse(SameParametersAsInBaseClassAndSameSignature
    {
        //this simply hides the method from the user
        //but user will still have the chance to cast to the BaseClass and
        //access the methods from there
    }
}

你是在具體談論Rectangle對象,還是在一個更通用的術語上,只是以它為例?

如果你正在談論一個更通用的術語,那么在重構模式中經常會出現這種情況。 這通常發生在對象上的集合中。 例如,如果您公開List<T>那么即使setter是私有的,人們仍然可以通過getter修改集合,因為他們實際上並沒有設置集合。

要解決這個問題,請考慮德米特定律 也就是說,當某人與一個對象暴露的集合進行交互時,他們是否真的要與對象本身進行交互? 如果是這樣,那么不應該公開該集合,而是該對象應該公開它需要的功能。

所以,再一次在集合的情況下,你最終會得到這樣的東西:

class SomeObject
{
    private List<AnotherObject> Things;

    public void AddAnotherObject(AnotherObject obj)
    {
        // Add it to the list
    }

    public void RemoveAnotherObject(AnotherObject obj)
    {
        // Remove it from the list
    }
}

當然,您可能還希望公開對象本身的一些副本供人們閱讀,但不能修改。 對於一個集合,我可能會這樣做:

public IEnumerable<AnotherObject> TheObjects
{
    get { return Things; }
}

這樣任何人都可以看到對象的當前狀態並枚舉它們,但它們實際上無法修改它。 不是因為它沒有setter,而是因為IEnumerable<T>接口沒有修改枚舉的選項。 只能枚舉它。

對於使用Rectangle的情況(或類似的東西, Rectangle不是一個通過值傳遞的結構),你會做一些非常相似的事情。 存儲私有對象並提供公共功能以通過類本身對其進行修改(因為我們所討論的是類需要知道其成員何時被修改)以及檢查它的功能而無法修改正在進行的操作檢查。 也許是這樣的事情:

class SomeObject
{
    private AnotherObject Thing;

    public AnotherObject TheThing
    {
        get { return Thing.Copy(); }
    }

    public void RenameThing(string name)
    {
        Thing.Name = name;
    }

    // etc.
}

在這種情況下,沒有詳細討論AnotherObject是什么(所以在某些方面考慮偽代碼),檢查內部對象的屬性返回它的副本,而不是實際對象的實際引用。 對於值類型,這是該語言的默認行為。 對於參考類型,您可能需要在此與性能之間取得平衡(如果創建副本是繁重的操作)。

在這種情況下,您還需要小心使對象的界面不直觀。 使用代碼可能希望能夠修改被檢查的內部對象,因為它公開了修改自身的功能。 事實上,他們可以修改他們擁有的副本。 你如何解決這個問題在很大程度上取決於對象的概念性質以及它們之間的相互關系,這是一個人為的例子並沒有真正傳達出來的。 您可以創建一個自定義DTO(甚至是一個結構),它只返回內部對象的可觀察屬性,這使得它更復雜,而不是原始對象。 您可能只是說它是intellisense評論中的副本。 您可以創建單獨的屬性以返回內部對象的單個數據元素而不是單個屬性以返回對象本身。 有很多選項,由您決定什么對您的對象最有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM