简体   繁体   English

C#泛型-从泛型类调用泛型方法

[英]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 我有以下类,并且我试图从ExportFileBaseBL类调用Compare方法,但是出现错误

Cannot implicitly convert type 'Class1' to 'T'. 无法将类型“ Class1”隐式转换为“ 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 type Class1<T> and return an instance of Class1<T> , not a more specific type than Class1<T> . 的问题是,你的抽象Compare方法被定义为接受类型的参数Class1<T>并返回的一个实例Class1<T>不是一个更具体的类型比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> . 但这是您的Class3.Compare方法尝试做的事情:调用T.Compare并假设输出将为T ,而实际上您只能确定它将是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> ); 上面的代码做出的错误假设类似于您自己的假设: parser.Parse将返回一个int仅因为int派生自object (就像您的情况一样, T必须派生自Class1<U> ); in fact, you can only be sure it will return an object . 实际上,您只能确定它将返回一个object

There are two ways I can see to fix this problem: make Class1<T>.Compare a generic method: 我可以通过两种方法解决此问题:使Class1<T>.Compare一个通用方法:

public abstract U Compare<U>(U otherObj) where U : Class1<T>;

...or relax the type specificity of your Class3.Compare method's return value: ...或放宽Class3.Compare方法的返回值的类型特异性:

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: 您还需要使Compare方法的定义通用:

public abstract Class1<T> Compare<T>(Class1<T> otherObj); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM