I have the following classes and I am trying to call Compare method from ExportFileBaseBL class but I get the error
Cannot implicitly convert type 'Class1' to 'T'. An explicit conversion exists (are you missing a cast?)
public abstract class Class1<T> where T: Class2
{
public abstract Class1<T> Compare(Class1<T> otherObj);
}
public abstract class Class3<T, U> where T: Class1<U>
where U: Class2
{
public T Compare(T obj1, T obj2)
{
if (obj1.Prop1 > obj2.Prop1)
{
return obj1.Compare(obj2); // Compiler Error here
}
else
{
return obj2.Compare(obj1); // Compiler Error here
}
}
}
Shouldn't the type conversion be implicit? Am I missing something?
The problem is that your abstract
Compare
method is defined to accept a parameter of typeClass1<T>
and return an instance ofClass1<T>
, not a more specific type thanClass1<T>
. But this is what yourClass3.Compare
method is attempting to do: callT.Compare
and assume the output will be aT
, when in fact you can only be sure it will be aClass1<U>
.To provide a simpler, more comprehensible example, suppose I had this class:
The above code makes a faulty assumption similar to your own: that
parser.Parse
will return anint
just becauseint
derives fromobject
(just as in your case,T
must derive fromClass1<U>
); in fact, you can only be sure it will return anobject
.There are two ways I can see to fix this problem: make
Class1<T>.Compare
a generic method:...or relax the type specificity of your
Class3.Compare
method's return value:Personally, I would prefer the second unless you absolutely need the first. All these generic type constraints can become very messy and burden you more than you expect when the complexity starts to grow like this.