【问题标题】:C# Generics - Calling generic method from a generic classC# 泛型 - 从泛型类调用泛型方法
【发布时间】:2011-02-02 17:12:55
【问题描述】:

我有以下类,我试图从 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
        }
    }

}

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

【问题讨论】:

    标签: c# generics casting explicit


    【解决方案1】:

    问题在于您的抽象Compare 方法被定义为接受Class1&lt;T&gt; 类型的参数并返回Class1&lt;T&gt; 的实例,不是比@ 更具体的类型 987654324@。但这就是您的 Class3.Compare 方法试图做的事情:调用 T.Compare 并假设输出将是 T,而实际上您只能确定它将是 Class1&lt;U&gt;

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

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

    上面的代码做了一个类似于你自己的错误假设:parser.Parse 将返回一个 int 只是因为 int 派生自 object (就像你的情况一样,T 必须派生自 @987654335 @);事实上,你只能确定它会返回一个object

    我认为有两种方法可以解决此问题:将Class1&lt;T&gt;.Compare 设为通用方法:

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

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

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

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

    【讨论】:

    • 谢谢丹,这回答了我的问题。
    • Jup jup,现在我们已经添加了比较方法的更新,我同意这个答案。
    【解决方案2】:

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

      return obj1.Compare<T>(obj2); 
    

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

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

    【讨论】:

    • Compare 方法不是通用的,因此它不会接受当前形式的类型参数。
    • 但是@Kyle 只是说明了它需要在父代码中修复的位置。他还需要在第一类比较方法中添加&lt;T&gt;
    • 那应该添加到答案中。我会添加它。
    • 常识,是的。不过,明确一点也无妨。 :)
    • @Kyle,当你回答问题时会发生这种情况,并且必须同时进行白天工作编码:)
    猜你喜欢
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 2012-04-21
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多