1

私の C# プロジェクトで奇妙な繰り返しテンプレート パターン(CRTP) を使用していますが、いくつか問題があります。上記のリンクから抜粋したコード:

public abstract class Base<T> where T : Base<T>{
    public T FluentMethod() {
        return (T)(this); 
    }
}

public class Derived : Base<Derived> {
}

美しい!次のようなことをしようとすると、問題が発生します。

public class SomeClass
{
    Base<T> GetItem() { /* Definition */ };
}

SomeClass は Base クラスの任意の実装を返すことができるはずですが、もちろん T は別のクラスにあるため、ここでは意味がありません。T コンパイルの代わりに Derived を配置しますが、Base から派生している限り、他のタイプのアイテムも返すことができるはずなので、これは私が望むものではありません。また、GetItem() は SomeClass オブジェクトの状態に応じて異なる型のオブジェクトを返す可能性があるため、SomeClass をジェネリックにすることも解決策ではありません。

ここで明らかな何かが欠けていますか、それとも CRTP の使用中にこれを行うことはできませんか?

4

2 に答える 2

3

メソッドをジェネリックとして宣言する必要があります。

using System;
public abstract class Base<T> where T : Base<T> {
    public T FluentMethod() {
        return (T)(this);
    }
}

public class Derived : Base<Derived> {
}

public class SomeClass {
    Base<T> GetItem<T>() where T : Base<T> {
        throw new NotImplementedException();
    }
}

プロパティにするには、クラス自体をジェネリックとして宣言する必要があります。

public class SomeClass<T> where T : Base<T> {
    Base<T> GetItem {
        get { throw new NotImplementedException(); }
    }
}
于 2011-11-14T13:03:55.960 に答える
0

パブリック メソッドをジェネリックとして作成しないでください。そうしないと、型宣言が別のレベルに達します。「Derived GetDerivedItem()」のようなさまざまなタイプのファクトリ クラスを作成します。

public class SomeClass {
    private Base<T> GetItem<T>() { /*implementation */ }

    public Derived GetDerivedItem() {
        return GetItem<Derived>();
    }
}
于 2011-11-14T13:13:36.507 に答える