我有以下情况:
// A public interface of some kind
public interface IMyInterface {
int Something { get; set; }
}
// An internal class that implements the public interface.
// Despite the internal/public mismatch, this works.
internal class MyInternalConcrete : IMyInterface {
public int Something { get; set; }
}
// A generic class with an interface-restricted type parameter.
// Note that the constraint on T uses the *public* interface.
// The instance is *never* exposed as a public, or even protected member.
public class MyClass<T> where T : IMyInterface, new() {
T myInterfaceInstance;
public MyClass() {
myInterfaceInstance = new T();
}
}
// Attempting to implement concrete class... Inconsistent Accessibility Error!
public class MySpecificClass : MyClass<MyInternalConcrete>
{
}
在尝试实现MySpecificClass时,我收到错误:
可访问性不一致:基类'App1.MyClass'不如类'App1.MySpecificT'
尽管内部,但MyInternalConcrete仍然可以实现公共接口,这一点很奇怪。并且由于它实现了接口,因此它应可用作MyClass的类型参数 - 因为T受约束在公共接口而不是内部类。
如果MyClass暴露了T,我会理解它失败了,就像我们没有使用泛型一样会失败:
public class MyClass<T> where T : IMyInterface, new() {
T myInterfaceInstance;
public MyClass() {
myInterfaceInstance = new T();
}
// This will fail with an internal T - inconsistent accessibility!
public T Instance {
get { return myInterfaceInstance; }
}
}
与上述相同,但没有泛型:
public class MyNonGenericClass {
MyInternalConcrete myInterfaceInstance;
public MyNonGenericClass() {
myInterfaceInstance = new MyInternalConcrete();
}
// This will fail - inconsistent accessibility!
// but removing it works, since the private instance is never exposed.
public MyInternalConcrete Instance {
get { return myInterfaceInstance; }
}
}
这是C#泛型的限制还是我只是误解了关于泛型如何工作的基本原理?
I also posted this thread on MSDN,但我被解雇,因为不知道我在说什么。我的担忧是否有效?
答案 0 :(得分:7)
“泛型类型的可见性是 泛型的交集 具有参数的可见性 类型即可。如果所有C的能见度, T1,T2和T3类型设置为公开, 那么C的可见性就是 也是公众;但如果能见度 这些类型中只有一种是私有的, 那么C的可见性就是 私人“。
因此,虽然您的示例是可能的,但它不符合定义的规则。
有关更明确的来源,请参阅C# spec的第25.5.5节(第399页)。
构造的类型C是 可以访问所有组件 可以访问C,T1,...,TN。更多 确切地说,可访问性域 对于构造类型是 可访问性的交集 未绑定泛型类型的域和 该类型的可访问性域 参数。
答案 1 :(得分:5)
由于以下原因,您所面临的这种限制是有道理的。
C#强类型,所以......
为了能够引用它定义的程序集范围之外的MySpecificClass,必须知道它的参数类型,以便为其实例生成强类型引用;但是内部定义的单独组件不知道MyInternalConcrete。
因此,如果在单独的程序集中,以下内容将无效:
MyClass<MyInternalConcrete> myInstance = new MySpecificClass();
这里单独的程序集不知道MyInternalConcrete,所以如何定义变量。
答案 2 :(得分:1)
如果允许,你可以将MyClass传递出程序集,突然之间,另一个程序集可以访问它不应该访问的内容 - MyInternalConcrete!