C# Generics - Calling generic method from a generic class
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: C开发者_如何学JAVAlass1<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 type Class1<T>
and return an instance of Class1<T>
, not a more specific type than Class1<T>
. But this is what your Class3.Compare
method is attempting to do: call T.Compare
and assume the output will be a T
, when in fact you can only be sure it will be a Class1<U>
.
To provide a simpler, more comprehensible example, suppose I had this class:
class Parser
{
public abstract object Parse(string text);
}
class Int32Parser
{
public int Parse(Parser parser, string text)
{
return parser.Parse(text);
}
}
The above code makes a faulty assumption similar to your own: that parser.Parse
will return an int
just because int
derives from object
(just as in your case, T
must derive from Class1<U>
); in fact, you can only be sure it will return an object
.
There are two ways I can see to fix this problem: make Class1<T>.Compare
a generic method:
public abstract U Compare<U>(U otherObj) where U : Class1<T>;
...or relax the type specificity of your Class3.Compare
method's return value:
public Class1<U> Compare(T obj1, T obj2)
{
// ...
}
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.
Call the method with the parameter type you declaring at your class level.
return obj1.Compare<T>(obj2);
You'll need to make the definition of the Compare method generic as well:
public abstract Class1<T> Compare<T>(Class1<T> otherObj);
精彩评论