4

1つのメソッド、つまり1つのオブジェクトのコンテンツを同じタイプの別のオブジェクトにコピーする機能を備えたインターフェイスを作成しました(実際の機能は質問とは無関係です)。

public interface IDeepClonable
{
    void DeepClone<T>(T other);
}

適切な実装に問題があります。

私が本当に望んでいるのは、このように実装することです(これは、IDeepClonableを実装するClassA内にあります)

public void DeepClone<ClassA>(ClassA other)
{
    this.A = other.A;
}

ただし、「other」オブジェクトはコンパイラによってClassAのインスタンスとして認識されないため、これは機能しません(なぜですか?)

'タイプパラメータTの制約は、(...)インターフェイスメソッドと一致する必要があるため、これも機能しません。

public void DeepClone<T>(T other) where T : ClassA
{
    this.A= other.A;
}

一般的な制約ではなくオブジェクトを取り込むようにインターフェイスを変更することですべての問題を解決できますが、より洗練された解決策を望んでいました。

インターフェイスをジェネリックインターフェイスに変えることでこれを解決することもできますが、そうすると、そのジェネリックインターフェイスにキャストする必要があります。

4

2 に答える 2

5

CRTPを使用しようとしています。

あなたは書く必要があります

public interface IDeepClonable<out T> where T : IDeepClonable<T>
{
    void DeepClone(T other);
}

public class ClassA : IDeepClonable<ClassA> {
    void DeepClone(ClassA other) { ... }
}

ただし、これは、使用するコードIDeepClonable自体が汎用になる必要があることを意味し、扱いにくくなります。

CLR型システムは、本当にやりたいことを実行するのに十分なほど豊富ではありません。

于 2012-05-07T15:55:09.447 に答える
0

問題は、インターフェースでジェネリックメソッドを宣言しており、派生クラスでそれとまったく同じように実装する必要があることです。

public class ClassA : IDeepClonable 
{ 
    void DeepClone<T>(T other) { /* some implementation here */ } 
} 

それとは違うものはうまくいきません。

とはいえ、なぜこの種の複雑さが必要なのか、ここではジェネリックは必要なく、次のように実装するだけです。

public interface IDeepClonable 
{ 
    void DeepClone(IDeepClonable other); 
} 

public class ClassA : IDeepClonable 
{ 
    void DeepClone(IDeepClonable other)
    {
         // just to be sure ....
         if (other is ClassA) 
         {
             var o = (ClassA)other;
             this.A = o.A; 
         }
    } 
} 
于 2012-05-07T16:04:37.463 に答える