Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用公共接口和内部类型参数的泛型_C#_.net_Generics_Interface - Fatal编程技术网

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();