Could you help me to understand the error in those case ?
public interface IGeneralInterface
{
}
public class A : IGeneralInterface
{
}
public class B : IGeneralInterface
{
}
public class SomeClass<TGenericType> where TGenericType : IGeneralInterface
{
private TGenericType internalValue;
public SomeClass(TGenericType InitValue)
{
internalValue = InitValue;
}
public TGenericType CreateAnother()
{
TGenericType val1 = new B(); //Error here: class B() could not be converted to TGenericType
return val1;
}
}
Even if I build the SomeClass<T>
as
SomeClass<IGeneralInterface> someClass = new SomeClass<IGeneralInterface>();
I explicity pass base interface to include all (?) cases and it still throw an error
Change
TGenericType val1 = new B(); //Error here: class B() could not be converted to TGenericType
To
IGeneralInterface val1 = new B();
You are trying to TypeCast IGeneralInterface
to TGenericType
which is the cause of error.
TGenericType
could have other constraints, like it inherits from ISpecificInterface
from which B
donot inherit. In this case the assignment becomes invalid.
Example:
public class SomeClass< TGenericType> where TGenericType : IGeneralInterface, ISpecificInterface
TGenericType val1 = new B(); // TGenericType should be ISpecificInterface also, B is not.
For above to run. IGenericInterface
should always be more specific than TGenericType
.
public class SomeClass <IGenericInterface>
Alternatively you could use is
keyword to find out whether the object is assignable to TGenericType
and then use the casting.
TGenericType val1 = default(TGenericType);
var val = new B();
if ( val is TGenericType)
{
val1 = (TGenericType)val;
}
EDIT For the below comment
how it could at runtime have additional requirements ? Everything I put in compiler listed here
CreateAnother()
creates instance of Type B
which is not generic.
Take below example
SomeClass<C> c = new SomeClass<C();
C another = c.CreateAnother(); // C is not assignable from B. (C is below). But It would be valid, if compiler did not flag the error
public class C : IGeneralInterface, IDisposable
{
}