9

ISnackクラスによって実装されたときに、デフォルトのパラメーターなしのコンストラクターが必要なインターフェイスがあります。基本的にこれ:

public interface ISnack<T> where T : new()
{

}

<T> where T : new()パラメーターなしのコンストラクターを強制するためだけに使用します。

次に、この方法でインターフェイスを実装します。

public class Cutlet : ISnack<Cutlet>
{

}

これは機能し、Cutletクラスにパラメーターのないコンストラクターがあることを確認するだけです。

今、私は抽象基本クラスを持っていますKitchen:

public abstract class Kitchen<T> where T : ISnack
{

}

要件は、 であるKitchen必要がある場所に制約がT必要であることISnackです。しかし、存在しないため、これは機能しませんISnackが、 しかありませんISnack<T>

これを試したら

public abstract class Kitchen<T> where T : ISnack<T>
{

}

それはコンパイルされず('T' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ISnack<T>')、私のコンテキストでは意味がありません。

型パラメーターISnackによる制約なしで s にパラメーターなしのコンストラクターを持たせることができれば、 inは簡単に. それについてどうやって行くのですか?TTKitchen<T>ISnack

4

3 に答える 3

14

制約を追加しないとできません。一般的な制約は累積的であるため、コンパイラを満足させるには、次のものが必要です。

public abstract class Kitchen<T> where T : ISnack<T>, new()

それでいいなら、そうしてください。それがうまくいかない場合は: new、オリジナルから を削除し、それなしで済ませる必要があります。これは思ったほど悪くはありませんが、コンパイルではなく実行に検証をプッシュすることを意味します。しかし、とにかく、制約Activator.CreateInstance<T>()がなくても、必要なことは実行します。new()したがって、次のように置き換えることができます:

T newObj = new T(); // validated by the compiler

と:

T newObj = Activator.CreateInstance<T>(); // not validated until executed

制約を削除するときの便利なトリックは次のとおりです。リフレクションを介して候補の型を見つけるユニット/統合テストを追加し、欠落している制約をテスト スイートの一部として検証します。

于 2012-10-09T11:41:59.603 に答える
3

2 番目のジェネリック パラメータを使用できます。

abstact class Kitchen<T, S> 
    where T : ISnack<S> 
    where S : new()
....

これで問題が解決します。

クラスに 2 番目のパラメーターを追加すると、.NET 2.0 が利用可能になってから直面したいくつかの問題が発生する可能性もあります。複雑な状況では、必要以上にジェネリック パラメータをクラスに追加しなければならない場合があります。通常、直接キャスト ( など) を追加して、汎用チェーンを分解し(SpecificType)base.MyTypeTPropertyます。コメント: 後でサンプルを探してみます

于 2012-10-09T12:14:11.683 に答える
1

制約を T に再度追加するだけです

public abstract class Kitchen<T> where T : ISnack<T>, new()   {      }
于 2012-10-09T11:42:40.037 に答える