C# 使用公共接口和内部类型参数的泛型
我有以下情况:C# 使用公共接口和内部类型参数的泛型,c#,.net,generics,interface,C#,.net,Generics,Interface,我有以下情况: // 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 c
// 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>
{
}
这是C泛型的一个局限性,还是我只是对泛型工作原理的一些基本误解
,但我被解雇了,因为我不知道自己在说什么。我的担心是正确的吗?根据 泛型类型的可见性为 泛型类型的交集 具有参数的可见性 类型。如果所有C的可见性, T1、T2和T3类型设置为公共, 那么C的可见性是 也公开;但如果 这些类型中只有一种是私有的, 那么C的可见性是 私人的 因此,虽然您的示例是可能的,但它不符合所定义的规则 有关更明确的来源,请参见第399页第25.5.5节 构造的类型C是 当其所有组件 C、 T1、…、TN是可访问的。更多 准确地说,可访问性领域 对于构造类型,是 可达性的交叉点 未绑定泛型类型的域和 类型的可访问性域 争论
根据这篇关于 泛型类型的可见性为 泛型类型的交集 具有参数的可见性 类型。如果所有C的可见性, T1、T2和T3类型设置为公共, 那么C的可见性是 也公开;但如果 这些类型中只有一种是私有的, 那么C的可见性是 私人的 因此,虽然您的示例是可能的,但它不符合所定义的规则 有关更明确的来源,请参见第399页第25.5.5节 构造的类型C是 当其所有组件 C、 T1、…、TN是可访问的。更多 准确地说,可访问性领域 对于构造类型,是 可达性的交叉点 未绑定泛型类型的域和 类型的可访问性域 争论
由于以下原因,您面临的这个约束是有意义的 C是强类型的,所以 为了能够在程序集范围之外引用MySpecificClass,您必须知道它的参数类型,以便生成对其实例的强类型引用;但是一个独立的程序集比内部定义更不了解MyInternalConcrete 因此,如果在单独的组件中,以下操作将不起作用:
MyClass<MyInternalConcrete> myInstance = new MySpecificClass();
在这里,单独的程序集不知道MyInternalConcrete,因此如何定义这样的变量。由于以下原因,您面临的约束是有意义的 C是强类型的,所以 为了能够在程序集范围之外引用MySpecificClass,您必须知道它的参数类型,以便生成对其实例的强类型引用;但是一个独立的程序集比内部定义更不了解MyInternalConcrete 因此,如果在单独的组件中,以下操作将不起作用:
MyClass<MyInternalConcrete> myInstance = new MySpecificClass();
在这里,单独的程序集不知道MyInternalConcrete,因此您如何定义这样的变量。如果允许,您可以将MyClass从程序集中传递出去,突然,另一个程序集可以访问它不应该访问的东西-MyInternalConcrete 如果允许的话,您可以将MyClass从程序集中传递出去,突然,另一个程序集可以访问它不应该访问的东西—MyInternalConcrete 那么,泛型实现的限制是什么?值得报告connect?允许引用程序集无法强引用的类型似乎不合逻辑。太棒了。谢谢关于类型交叉的那句话让我找到了问题的根源@范斯利:为什么不呢?这似乎是限制的一个特例,它禁止派生类型比它们的父类型更容易访问,但我不明白为什么能够定义这样的类型没有用。在许多情况下,从外部代码的角度来看,类型的父级应该是实现细节。在公共类型W和X都应该派生自公共类型Z的关系树中,有时使用中间类型Y是有用的,外部代码应该对其有任何合法的用途。在这种情况下,要求Y是公共的有什么好处?@supercat它不是一个实现细节,泛型定义是类型定义的一部分。当我听到实现细节时,我想到了组合和封装。我可以理解,在某种情况下,泛型参数类型可能不会暴露在虚拟方法、属性等类型的契约中,但对我来说这似乎是一个特例。那么,泛型实现的限制是什么?值得报告connect?允许引用程序集无法强引用的类型似乎不合逻辑。太棒了。谢谢那句关于
类型的交叉让我找到了问题的根源@范斯利:为什么不呢?这似乎是限制的一个特例,它禁止派生类型比它们的父类型更容易访问,但我不明白为什么能够定义这样的类型没有用。在许多情况下,从外部代码的角度来看,类型的父级应该是实现细节。在公共类型W和X都应该派生自公共类型Z的关系树中,有时使用中间类型Y是有用的,外部代码应该对其有任何合法的用途。在这种情况下,要求Y是公共的有什么好处?@supercat它不是一个实现细节,泛型定义是类型定义的一部分。当我听到实现细节时,我想到了组合和封装。我可以理解,在某种情况下,虚方法、属性等类型的契约中可能没有公开泛型参数类型,但对我来说这似乎是一个特例。这个参数是万无一失的。我完全理解这一点。谢谢——我的思想最近一直在这个空间徘徊——很高兴我能增加我的两分钱价值:我不记得你可以回到一般定义上来。它完美地解释了为什么它需要知道构成定义的所有类型。这在常规类定义中不会发生,因此我假设同样的情况也适用于泛型。这是完全有道理的。这个论点是万无一失的。我完全理解这一点。谢谢——我的思想最近一直在这个空间徘徊——很高兴我能增加我的两分钱价值:我不记得你可以回到一般定义上来。它完美地解释了为什么它需要知道构成定义的所有类型。这在常规类定义中不会发生,因此我假设同样的情况也适用于泛型。现在这是完全有道理的。
MyClass<MyInternalConcrete> myInstance = new MySpecificClass();