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て、出力が になると仮定しTます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ます。実際、確実に返されるのは.intintobjectTClass1<U>object

この問題を解決するには、次の 2 つの方法があります。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 に答える