I have the following situation:
// 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>
{
}
When trying to implement MySpecificClass, I get the error "Inconsistent accessibility: base class 'App1.MyClass' is less accessible than class 'App1.MySpecificT'".
Where it gets weird is that MyInternalConcrete, despite being internal, can still implement a public interface. And since it implements the interface, then it should be useable as a type parameter for MyClass - because T is constrained on the public interface and not the internal class.
I would understand it failing if MyClass exposed T, just as it would fail if we weren't using generics:
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; }
}
}
And same as above, but without generics:
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; }
}
}
Is this a limitation of the C# generics or am I simply misunderstanding something fundamental about how generics work?
I also posted this thread on MSDN, but I'm being dismissed as not knowing what I'm talking about. Is my concern even valid?