通常我希望某些類C1的某些(或全部)函數只能從另一個類C2中訪問,因爲C2是一種代理,它擁有類型C1(例如:「神經元」類的方法,如「connect()」,只能從「Brain」訪問)。我認爲這與C#不是直接可能的,不像繼承,我們可以使用像「private」或「protected」這樣的關鍵字指定可見性。如何在c中控制類的可見性
這種情況下的最佳做法是什麼?
通常我希望某些類C1的某些(或全部)函數只能從另一個類C2中訪問,因爲C2是一種代理,它擁有類型C1(例如:「神經元」類的方法,如「connect()」,只能從「Brain」訪問)。我認爲這與C#不是直接可能的,不像繼承,我們可以使用像「private」或「protected」這樣的關鍵字指定可見性。如何在c中控制類的可見性
這種情況下的最佳做法是什麼?
如果C1
不能由任何人,但C2
進行訪問,然後做出一個C1
類private
的C2
。
public class C2
{
public C2() { }
private class C1
{
public C1() { }
}
}
然而,如果C1
能的C2
外部訪問,那麼你將需要某種key
通入的C2
的ctor
,以確保它是一個值得信賴的代理。
public class C1
{
public C1(string key)
{
// verify that it's a valid proxy or user of this class via the key
}
}
創建你的類組件,並宣佈內部類,應該是不可見的外部世界爲internal
:
的
internal
關鍵字是訪問修飾符類型和類型成員。內部類型或成員都可以訪問只在同一程序文件
所以,這樣的事情:
namespace YourAssembly.Classes
{
internal class C1
{
public void Foo()
{
}
}
public class C2
{
public void DoFoo()
{
new C1().Foo();
}
}
}
這裏C2
是從其他組件訪問,而C1
只能從內同一訪問部件。
對於整個DLL而言,「內部」是可見的,而不是名稱空間。 – RoadBump
常用於測試目的的技巧是使用InternalsVisibleToAttribute。你把它應用到一個組件(EXE或DLL),如定義爲internal
這個
[assembly: InternalsVisibleTo("NameOfFriendAssembly")]
類(和其他類型)和成員,然後將可見內部的原因,但也向大會NameOfFriendAssembly
在我看來,最好你是做這樣的事情:
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>(); }
}
如果您不謹慎,仍然可以從程序集內的任何其他類調用Connect()。真正需要的是編譯器支持這個問題恕我直言。 – Yekoor
@Yekoor:我不同意。你看,我認爲你犯了一個非常常見的錯誤,那就是根據類的概念而不是API訪問來考慮代碼可見性。 **'Neuron'方法是公開的,因爲DLL的外部客戶端應該被允許訪問它,而不是因爲'Brain'應該能夠連接'Neuron' **。在你自己的庫中,你有責任不要調用不應該被調用的方法。代碼可見性應該只用於控制依賴於你的DLL的項目,並且用'internal'關鍵字來控制。 –
你寫的東西與問題的定義不一致。我沒有圖書館,儘管我沒有明確說明它,所以我不認爲就API訪問而言。如果我們理論上可以將它委託給編譯器,那麼爲什麼它應該是我自己的責任,就像繼承訪問控制一樣? – Yekoor
是的,我忘了提,私有類是不是一種選擇,因爲C2的功能必須與其他幾類訪問。 – Yekoor
@Yekoor,請參閱我的更新。 –
該解決方案通過添加運行時執行來解決編譯時問題。這不是正確的做法。 –