First off: I know there are a ton of "Cannot implicitly convert type" questions, but my question is more trying to wrap my head around why a specific combination of interfaces and generics does not compile. I've not been able to find an answer, so any pointer are welcome.
Basically, my problem is this:
I have a set of classes (base classes), all implementing a single interface. On top of this I want to build a "derived" interface that references the first set of classes set of classes. Finally, I have a static method, which takes an instance of a base class, and depending on the base class, returns an instance of the correct derived class.
Something like this (implemented in a .NET standard 2.0 class library):
public static class GenericClass
{
public static IDerived<IBase> Create(IBase base)
{
//if typeof a is
return new DerivedImplementedA(){Value = (ImplementationA) base};
}
}
However, I cannot return a DerivedImplementedA
class from a method with return signature IDerived<IBase>
, although DerivedImplementedA is implemented as follows:
public class DerivedImplementedA : IDerived<ImplementationA>
{
public ImplementationA Value { get; set; }
}
In my head, since DerivedImplementedA
implements IDerived
with the generic parameter ImplementationAd
, which in turn implements IBase
, it would be perfectly fine to return DerivedImplementedA
in cases where a IDerived<IBase>
is expected. However, this is not the case. If I try the following
public static class GenericClass
{
public static IDerived<IBase> Create(IBase a)
{
var temp = (ImplementationA) a;
return (IDerived<IBase>) new DerivedImplementedA(){ Value = temp};
}
}
I get the following warning:
"Suspicious cast: there is no type in the solution which is inherited from both DerivedImplementedA and IDerived". I suspect the message is key, but as I said, in my head this works out just fine. What am I missing?
Or, how can I solve this issue in a way that actually compiles?
Complete example for completeness:
public interface IBase
{
int A { get; set; }
}
public class ImplementationA : IBase
{
public int A { get; set; }
}
public interface IDerived<TBase>
where TBase: IBase
{
TBase Value { get; set; }
}
public class DerivedImplementedA : IDerived<ImplementationA>
{
public ImplementationA Value { get; set; }
}
public static class GenericClass
{
public static IDerived<IBase> Create(IBase a)
{
var temp = (ImplementationA) a;
return (IDerived<IBase>) new DerivedImplementedA(){ Value = temp};
}
}