5

我有以下类,我试图从 ExportFileBaseBL 类调用 Compare 方法,但我收到错误

无法将类型“Class1”隐式转换为“T”。存在显式转换(您是否缺少演员表?)

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
        }
    }

}

类型转换不应该是隐式的吗?我错过了什么吗?

4

2 回答 2

4

问题是您的抽象Compare方法被定义为接受类型参数Class1<T>返回 的实例Class1<T>而不是Class1<T>. 但这就是您的Class3.Compare方法尝试做的事情:调用T.Compare并假设输出将是 a T,而实际上您只能确定它将是 a Class1<U>

为了提供一个更简单、更易于理解的示例,假设我有这个类:

class Parser
{
    public abstract object Parse(string text);
}

class Int32Parser
{
    public int Parse(Parser parser, string text)
    {
        return parser.Parse(text);
    }
}

上面的代码做出了一个类似于您自己的错误假设:这parser.Parse将返回一个intjust because intderived from object(就像在您的情况下,T必须派生自Class1<U>);事实上,你只能确定它会返回一个object.

我可以看到有两种方法可以解决这个问题:制作Class1<T>.Compare一个通用方法:

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

...或放宽Class3.Compare方法返回值的类型特异性:

public Class1<U> Compare(T obj1, T obj2)
{
    // ...
}

就个人而言,除非您绝对需要第一个,否则我更喜欢第二个。当复杂性开始像这样增长时,所有这些泛型类型约束可能会变得非常混乱并给您带来超出预期的负担。

于 2011-02-02T17:22:51.020 回答
2

使用您在类级别声明的参数类型调用该方法。

  return obj1.Compare<T>(obj2); 

您还需要将 Compare 方法的定义设为通用:

public abstract Class1<T> Compare<T>(Class1<T> otherObj); 
于 2011-02-02T17:16:33.070 回答