C# 在c中如何按所有者控制类可见性#
通常我希望某些类C1的某些(或全部)函数只能从另一个类C2中访问,因为C2是一种代理,它拥有C1类型的对象(例如,类“Neuron”的方法,如“connect()”,应该只能从“Brain”访问)。我假设这在C#中不可能直接实现,这与继承不同,继承可以使用关键字“private”或“protected”指定可见性C# 在c中如何按所有者控制类可见性#,c#,class,visibility,C#,Class,Visibility,通常我希望某些类C1的某些(或全部)函数只能从另一个类C2中访问,因为C2是一种代理,它拥有C1类型的对象(例如,类“Neuron”的方法,如“connect()”,应该只能从“Brain”访问)。我假设这在C#中不可能直接实现,这与继承不同,继承可以使用关键字“private”或“protected”指定可见性 在这种情况下,最好的做法是什么?如果C1只能被C2访问,那么将C1设为C2的私有类 public class C2 { public C2() { } private
在这种情况下,最好的做法是什么?如果
C1
只能被C2
访问,那么将C1
设为C2
的私有类
public class C2
{
public C2() { }
private class C1
{
public C1() { }
}
}
但是,如果可以在C2
之外访问C1
,则需要将某种键
传入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();
}
}
}
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>(); }
}
此处C2
可从其他组件访问,而C1
只能从同一组件内访问。通常用于测试目的的技巧是使用。您可以像这样将其应用于程序集(exe或dll)
[assembly: InternalsVisibleTo("NameOfFriendAssembly")]
类(和其他类型)和定义为内部
的成员将在内部可见,但也对程序集可见NameOfriendaAssembly
在我看来,对您来说最好的方法是这样做:
namespace YourAssembly.Classes
{
internal class C1
{
public void Foo()
{
}
}
public class C2
{
public void DoFoo()
{
new C1().Foo();
}
}
}
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>(); }
}
欧元区的公共界面
{
双GetValue();
列出GetDependents();
列出GetWeights();
}
内类神经元:伊内隆
{
//INeuron的实施
// ...
//只有自己的类知道的方法的实现
公共连接(神经元目标,双重重量)
{
...
}
}
公共阶层的头脑
{
私有列表_allNeurons=新列表();
公共大脑()
{
神经元n1=新神经元();
神经元n2=新神经元();
n1.连接(n2,0.5);
_所有神经元。添加(n1);
_所有神经元。添加(n2);
}
public IEnumerable GetAllNeurons(){return allNeurons.Cast();}
}
是的,我忘了提到私有类不是选项,因为C2的函数必须可以被其他几个类访问。此解决方案通过添加运行时执行来解决编译时问题。这不是正确的方法。@MichaelPerrenoud:问题是编译时的问题。这里的目的是防止其他程序员访问他们不应该访问的方法。您的解决方案意味着在运行时使用逻辑,即每次调用方法时都要确定一个键是正确的。此解决方案会损害代码的性能…internal
对整个DLL可见,而不是对命名空间可见。如果不小心,您仍然可以从程序集中的任何其他类调用Connect()。真正需要的是编译器对这个问题的支持。@Yekoor:我不同意。你看,我认为你犯了一个非常常见的错误,那就是从类的概念而不是API访问的角度来考虑代码的可见性。Neuron
上的方法是公开的,因为应该允许DLL的外部客户端访问它,而不是因为Brain
应该能够连接Neuron
s。在您自己的库中,您有责任不调用不应该调用的方法。代码可见性应仅用于控制依赖于DLL且由internal
关键字控制的项目。您编写的内容与问题的定义不兼容。我没有一个库,即使我没有显式地声明它,所以我不考虑API访问。如果理论上我们可以像继承访问控制一样将其委托给编译器,那为什么这是我自己的责任呢?我要说的是,方法可见性不应该用于建模问题,而应该用于限制DLL可用的内容(主要是限制依赖项)。这与大脑
是否应该能够访问Neuron.Connect()
无关