繁体   English   中英

使用公共接口和内部类型参数的泛型

[英]Generics using public interfaces and internal type parameters

我有以下情况:

// 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.MySpecificT”类相比,基类“ App1.MyClass”的访问性较差

奇怪的是,尽管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#泛型的限制,还是我只是误解了泛型工作原理的一些基本知识?

我也在MSDN上发布了该线程 ,但是由于不知道我在说什么而被解雇。 我的担忧是否有效?

根据这篇关于C#泛型的文章

泛型类型的可见性是泛型类型与参数类型的可见性交集 。如果所有C,T1,T2和T3类型的可见性都设置为public,则C的可见性也是public;但是如果只有这些类型之一的可见性是私有的,那么C的可见性就是私有的。”

因此,尽管您的示例是可能的,但它不符合所定义的规则。

有关更明确的来源,请参见C#规范的 25.5.5节(第399页)。

当可访问其所有组件C,T1,...,TN时,可访问构造的类型C。 更准确地说,用于构造类型的可访问性域是未绑定通用类型的可访问性域与类型参数的可访问性域的交集。

由于以下原因,您面临的这个约束很有意义。

C#是强类型的,所以...

为了能够在程序集定义的范围之外引用MySpecificClass,必须知道其参数类型,以便生成对其实例的强类型引用。 但是与内部定义不同的单独程序集不了解MyInternalConcrete。

因此,如果在单独的组件中,则以下内容将不起作用:

MyClass<MyInternalConcrete> myInstance = new MySpecificClass();

在这里,单独的程序集不了解MyInternalConcrete,因此如何定义变量。

如果允许的话,您可以将MyClass传递出程序集,突然之间,另一个程序集可以访问它不应该访问的内容-MyInternalConcrete!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM