2012-12-24 33 views
4

通常我希望某些類C1的某些(或全部)函數只能從另一個類C2中訪問,因爲C2是一種代理,它擁有類型C1(例如:「神經元」類的方法,如「connect()」,只能從「Brain」訪問)。我認爲這與C#不是直接可能的,不像繼承,我們可以使用像「private」或「protected」這樣的關鍵字指定可見性。如何在c中控制類的可見性

這種情況下的最佳做法是什麼?

回答

3

如果C1不能由任何人,但C2進行訪問,然後做出一個C1privateC2

public class C2 
{ 
    public C2() { } 

    private class C1 
    { 
     public C1() { } 
    } 
} 

然而,如果C1能的C2外部訪問,那麼你將需要某種key通入的C2ctor,以確保它是一個值得信賴的代理

public class C1 
{ 
    public C1(string key) 
    { 
     // verify that it's a valid proxy or user of this class via the key 
    } 
} 
+0

是的,我忘了提,私有類是不是一種選擇,因爲C2的功能必須與其他幾類訪問。 – Yekoor

+0

@Yekoor,請參閱我的更新。 –

+0

該解決方案通過添加運行時執行來解決編譯時問題。這不是正確的做法。 –

5

創建你的類組件,並宣佈內部類,應該是不可見的外部世界爲internal

internal (C# Reference)

internal關鍵字是訪問修飾符類型和類型成員。內部類型或成員都可以訪問只在同一程序文件

所以,這樣的事情:

namespace YourAssembly.Classes 
{ 
    internal class C1 
    { 
     public void Foo() 
     { 

     } 
    } 

    public class C2 
    { 
     public void DoFoo() 
     { 
      new C1().Foo();  
     } 
    } 
} 

這裏C2是從其他組件訪問,而C1只能從內同一訪問部件。

+0

對於整個DLL而言,「內部」是可見的,而不是名稱空間。 – RoadBump

0

常用於測試目的的技巧是使用InternalsVisibleToAttribute。你把它應用到一個組件(EXE或DLL),如定義爲internal這個

[assembly: InternalsVisibleTo("NameOfFriendAssembly")] 

類(和其他類型)和成員,然後將可見內部的原因,但也向大會NameOfFriendAssembly

0

在我看來,最好你是做這樣的事情:

public interface INeuron 
{ 
    double GetValue(); 
    List<INeuron> GetDependents(); 
    List<double> GetWeights(); 
} 

internal class Neuron : INeuron 
{ 
    // implementation of INeuron 
    // ... 

    // implementation of methods only known to own classes 
    public void Connect(Neuron target, double weight) 
    { 
     ... 
    } 
} 

public class Brain 
{ 
    private List<Neuron> _allNeurons = new List<Neuron>();  

    public Brain() 
    { 
     Neuron n1 = new Neuron(); 
     Neuron n2 = new Neuron(); 
     n1.Connect(n2,0.5); 
     _allNeurons.Add(n1); 
     _allNeurons.Add(n2); 
    } 

    public IEnumerable<INeuron> GetAllNeurons() { return _allNeurons.Cast<INeuron>(); } 
} 
+0

如果您不謹慎,仍然可以從程序集內的任何其他類調用Connect()。真正需要的是編譯器支持這個問題恕我直言。 – Yekoor

+0

@Yekoor:我不同意。你看,我認爲你犯了一個非常常見的錯誤,那就是根據類的概念而不是API訪問來考慮代碼可見性。 **'Neuron'方法是公開的,因爲DLL的外部客戶端應該被允許訪問它,而不是因爲'Brain'應該能夠連接'Neuron' **。在你自己的庫中,你有責任不要調用不應該被調用的方法。代碼可見性應該只用於控制依賴於你的DLL的項目,並且用'internal'關鍵字來控制。 –

+0

你寫的東西與問題的定義不一致。我沒有圖書館,儘管我沒有明確說明它,所以我不認爲就API訪問而言。如果我們理論上可以將它委託給編譯器,那麼爲什麼它應該是我自己的責任,就像繼承訪問控制一樣? – Yekoor