2012-10-09 6 views
6

私は、インターフェイスで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 
{ 

} 

要件はKitchenTISnackあるべき制約を持つべきであるということです。 しかし、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>')をコンパイルしませんし、また私の文脈で意味がありません。

私はT型パラメータによって制限することなくパラメータなしのコンストラクタを持つようにISnack秒を強制することができれば、その後、Kitchen<T>Tを簡単ISnackである可能性があります。それについてどうやって行くの?

答えて

10

制約を追加しない限りできません。

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

ことに問題がない場合は、が、その後ことを実行します。一般的な制約は、あなたが持っている必要がありますので、コンパイラを幸せにするために、累積されます。うまくない場合は、: newを元のものから削除し、それを削除してください。これは聞こえるほど悪くはありませんが、コンパイルではなく実行に検証を下すことを意味します。しかし、Activator.CreateInstance<T>()は、とにかく、あなたが必要とするものをまだ実行しています - new()の制約がなくても。削除制約があることができたときに

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

便利なトリック:

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

で:だから、置き換えることができます反射を経て候補タイプを見つけユニット/統合テストを追加し、不足している制約を検証あなたのテストスイートの一部として。これはあなたの問題を解決します

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

+0

Marc、Ditto!あなたは私が試したことのすべてを概説しました。Hmmmランタイムは、私が推測しているオプションです – nawfal

+1

@nawfal OKなら、キッチンに第2引数を追加することができます: 'abstact class Kitchen T:ISnack S:new() ' –

+0

@FelixK。別の答えにすることはできますか? – nawfal

1

単にあなたが第二の一般的なパラメータを使用することができます

再びTに
public abstract class Kitchen<T> where T : ISnack<T>, new() {  } 
3

を制約を追加します。

クラスに2番目のパラメータを追加すると、.NET 2.0が使用可能なので直面していたいくつかの問題が発生する可能性があります。いくつかの複雑な状況では、より一般的なパラメータをクラスに追加する必要があります。通常、私はより多くの直接キャスト((SpecificType)base.MyTypeTPropertyのような)を追加することによってジェネリックチェーンを分解します。 コメント:サンプルを後で探します。

+0

でもこれはうまくいきますが、Marcが提案したものよりもエレガントではないと思います – nawfal

+0

@nawfalもちろん、もっと複雑な状況では問題を引き起こす可能性があります。私はあとで例を掲載するかもしれない。 –

関連する問題