我有以下情况:
// 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 MyClasswhere T : IMyInterface, new() { T myInterfaceInstance; public MyClass() { myInterfaceInstance = new T(); } } // Attempting to implement concrete class... Inconsistent Accessibility Error! public class MySpecificClass : MyClass { }
在尝试实现MySpecificClass时,我收到错误:
可访问性不一致:基类'App1.MyClass'比类'App1.MySpecificT'更难访问
令人感到奇怪的是MyInternalConcrete尽管是内部的,仍然可以实现公共接口.并且由于它实现了接口,因此它应该可用作MyClass的类型参数 - 因为T受限于公共接口而不是内部类.
如果MyClass暴露T,我会理解它失败了,就像我们没有使用泛型一样会失败:
public class MyClasswhere 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#泛型的限制还是我只是误解了关于泛型如何工作的基本原理?
我也在MSDN上发布了这个帖子,但是因为不知道我在说什么而被解雇了.我的担忧是否有效?
根据这篇关于C#泛型的文章
" 泛型类型的可见性是泛型类型与参数类型可见性的交集.如果所有C,T1,T2和T3类型的可见性都设置为公共,那么C的可见性也是公开的;但如果只有其中一种类型的可见性是私有的,那么C的可见性就是私有的."
因此,虽然您的示例是可能的,但它不符合定义的规则.
有关更明确的来源,请参阅C#规范的第25.5.5节(第399页).
当所有组件C,T1,...,TN都可访问时,可以访问构造的类型C. 更确切地说,构造类型的可访问性域是未绑定泛型类型的可访问域与类型参数的可访问域的交集.
您面临的这种限制因为以下原因而有意义.
C#是强类型的,所以......
为了能够引用它所定义的程序集范围之外的MySpecificClass,必须知道它的参数类型,以便为其实例生成强类型引用; 但是一个单独的程序集比内部定义不知道MyInternalConcrete.
因此,如果在单独的程序集中,以下内容将无法工作:
MyClassmyInstance = new MySpecificClass();
这里单独的程序集不知道MyInternalConcrete,所以如何定义变量.