5

インターフェイスと、インターフェイスを実装する2つのクラスがあります。クラスにはジェネリック型があります。あるクラスのインスタンスから別のクラスにクローンを作成したいと思います。

interface IFoo
{
    // stuff
}

class Foo<T> : IFoo
{
    // foo stuff
    // ifoo implementation
}

class Bar<T> : IFoo
{
    // bar stuff
    // ifoo implementation
}

私はフーを持っていて、バーが欲しいです。Barには、IFooのパラメーターを受け取るコピーコンストラクターがあります。クローンを実装するための拡張メソッドを作成しました。

public static Bar<T> Clone<T>(this IFoo foo) 
{
    return new Bar<T>(foo);
}

メソッドを呼び出すには、次のタイプが必要です。

someFoo.Clone<T> ...

拡張メソッドを変更してメソッドを呼び出すときに型の宣言を省略する方法、またはその他の方法で、基になる型を気にせずにインスタンスを渡すことができるようにする方法はありますか?

更新 これは、状況をよりよく説明するためにこれがどのように使用されているかです。

メソッドでは、コレクションを繰り返し、IFooの列挙を返します。このメソッドでは、ソースコレクションの属性を調べて、Fooのタイプを判別します。

IFoo foo = null;

string type = element.Attribute("Type").Value;
switch (type)
{
    case "int":
        foo = new Foo<int>();
        break;

    case "string":
        foo = new Foo<string>();
        break;

    // etc
}
// other stuff

yield return foo;

呼び出し元のメソッドにはリストがあります。後で、このリストから個々のアイテムを選択して使用します。その時点で、FooではなくBarが必要です。リストから選択すると、インスタンスはタイプIFooであり、「thisIFoofoo」の拡張メソッドのみが表示されます。IFooをFooにキャストしたくないので、Tのタイプを再宣言する必要があります。FooにBarにそれが何であるかを伝えてもらいたいだけです。これは可能ですか?

4

5 に答える 5

2

したがって、すべて問題ありませんが、構文を使用できるようにしたい

someFoo.Clone()

それ以外の

someFoo.Clone<int>()

明示的に配置するのではなく、int を暗示する必要がありますか?

コード例でそれができない理由は、 IFoo が を作成するために必要なジェネリック型 T を参照していないためBar<T>です。

別のインターフェースが本当に必要であることをお勧めします。IFoo<T>

それがあり、拡張メソッドが次のようになっている場合:

public static Bar<T> Clone<T>(this IFoo<T> foo) 
{
    return new Bar<T>(foo);
}

そうすれば問題なく使えます

IFoo<int> someFoo = new Foo<int>();
Bar<int> someBar = someFoo.Clone();

それが役立つことを願っています

于 2009-02-19T04:41:15.580 に答える
0

これはインスピレーションに役立ちますか?:この浅いコピー クラスをどのように改善しますか?

基本的に、これは一般的なリフレクション ベースのプロパティ コピー メソッドです。やってみて。

于 2009-02-18T23:11:12.003 に答える
0

メソッドをそのように定義してみてください

public static Bar<T> Clone<T>(this Foo<T> foo)
{
    return new Bar<T>(foo);
}

このように、パラメーターはジェネリック型を持ち、コンパイラーは型を推測するためのソースを持ちます。

于 2009-02-19T00:56:26.493 に答える
0

ディープ コピー クローンを完全に制御する必要がある場合は、次のパターンが非常に適しています。

public class FooBase
{
    private int x;

    public FooBase() { /* standard contructor */ }

    protected FooBase(FooBase clone)
    {
        this.x = clone.x;
    }

    public FooBase Clone() { return new FooBase(this); }
}

public class Foo : FooBase
{
    private int y;

    public Foo() { /* standard contructor */ }

    protected Foo(Foo clone) : base(clone)
    {
        this.y = clone.y;
    }

    public Foo Clone() { return new Foo(this); }
}

複製用に保護されたコンストラクターを定義します。これにより、派生クラスは基本クラスの値を複製できます。このパターンは手動で作成する (または適切な T4 テンプレートを使用して生成する) 必要がありますが、ディープ クローニングには非常に適しています。

更新:私は質問を誤解しており、既にクローン作成を実装していると思います。Freddy の言うとおりです。コンパイラは、推論すべき型を認​​識している必要があり、IFoo 型からそれを実行することはできません。ただし、(this Foo< T > foo)で実行できます。

于 2009-02-18T23:38:34.217 に答える
0

シナリオで機能する場合は、IFoo<T>. また、特定の拡張メソッドを使用することを気にしない場合は、Foo<T>. コンパイラが適切な型を推測できるように、T を参照するものを渡す必要があります。

于 2009-02-18T23:30:35.703 に答える