.NETで総称インデクサーを定義できないのはなぜですか?

.net c# generics

なぜ.NETで総称インデクサーを作成できないのですか?

次のコードはコンパイラエラーをスローします。

public T this [文字列キー] {get {/ *ジェネリック型Tを返す * /}}

これは、一般的なメンバーコレクション用の一般的なインデクサーを作成できないということですか?

  42  6


ベストアンサー

これが役に立つ場所です。 オプションを宣言するために強く型付けされた `+ OptionKey +`があるとします。

public static class DefaultOptions
{
    public static OptionKey SomeBooleanOption { get; }
    public static OptionKey SomeIntegerOption { get; }
}

オプションが `+ IOptions +`インターフェースを介して公開される場合:

public interface IOptions
{
    /* since options have a default value that can be returned if nothing's
     * been set for the key, it'd be nice to use the property instead of the
     * pair of methods.
     */
    T this[OptionKey key]
    {
        get;
        set;
    }

    T GetOptionValue(OptionKey key);
    void SetOptionValue(OptionKey key, T value);
}

コードはそれから素敵な強く型付けされたオプションストアとしてジェネリックインデクサーを使うことができます:

void Foo()
{
    IOptions o = ...;
    o[DefaultOptions.SomeBooleanOption] = true;
    int integerValue = o[DefaultOptions.SomeIntegerOption];
}

27


プロパティはC#2.0 / 3.0ではジェネリックにすることはできないので、ジェネリックインデクサーを持つことはできません。

18


理由はわかりませんが、インデクサーは単なる構文糖衣です。 代わりに一般的なメソッドを書くと、同じ機能が得られます。 例えば:

public T GetItem(string key){/ *ジェネリック型Tを返す。 * /}

16


あなたはできる;宣言から「++」部分を削除するだけで正常に機能します。 i.e.

public T this[string key]
{
   get { /* Return generic type T. */ }
}

(クラスが `+ T +`という名前の型パラメーターを持つジェネリックであると仮定します)。

11


私は、 “indexed”項目への直接参照を配らずにインデクサーを持つことができるのが好きです。 以下に簡単な「コールバック」インデクサークラスを書きました…​

R =インデクサーから返された型P =インデクサーに渡された型

インデクサが実際に行うことは、操作をデプロイヤに渡し、それらが実際に発生して返されるものを管理できるようにすることだけです。

パブリッククラスGeneralIndexer {//パブリックデリゲートR gen_get(P parm);パブリックデリゲートvoid gen_set(P parm、R value);パブリックデリゲートP [] key_get();

//イベントpublic event gen_get GetEvent;公開イベントgen_set SetEvent;公開イベントkey_get KeyRequest。

public R this [P parm] {get {return GetEvent.Invoke(parm);} set {SetEvent.Invoke(parm、value);} }}

公開P []キー{get {return KeyRequest.Invoke();} }}

}

プログラムやクラスで使用するには:

private GeneralIndexer TimeIndex = new GeneralIndexer();

{TimeIndex.GetEvent = new GeneralIndexer.gen_get(TimeIndex_GetEvent); TimeIndex.SetEvent = new GeneralIndexer.gen_set(TimeIndex_SetEvent); TimeIndex.KeyRequest = new GeneralIndexer.key_get(TimeIndex_KeyRequest);

}

特に、あなたがあなたのリストへのアクセスを監視したり、何かがアクセスされたときに特別な操作をしたい場合、チャンピオンのように働きます。

2


私がこれを使用できると思うことができる唯一のものはこれらの線に沿った何かです:

var settings = ConfigurationSection.AppSettings;
var connectionString = settings["connectionString"];
var timeout = settings["timeout"];

しかし、これは実際にあなたに何も買わない。 丸かっこ( `+(int)settings [” timeout “] +`のように)を山かっこで置き換えましたが、自由にできるように追加の型安全性はありません

var timeout = settings["connectionString"];

強く型付けされているが静的に型付けされていないものがある場合は、_dynamic_キーワードを付けてC#4.0まで待つことをお勧めします。

1


最近のC-sharpでは、戻り型を “dynamic”として宣言できます。 これはC#ランタイムがあたかもそれがあなたが思っているタイプであるかのようにコードの中でそれを使うことを許し、そして正しいことを確かめるために実行時にチェックすることを除いて “object”を使うことと同じです。

0


タイトルとURLをコピーしました