3

明確にするために、ポインターからポインターへの動作が必要です。この質問の目的は、クリーンで読みやすいコードを生成することです。

Dictionary.TryGetValue複数の呼び出しの結果をチェックする条件を含むコードがあります。必要なすべてのオブジェクトを 1 回の呼び出しで取得できればよりクリーンになるため、次のことを可能にする拡張機能を作成したいと考えました。

Dictionary<string, string> myDictionary; // Initialized somewhere

string x, y, z;
bool foundAllEntries = myDictionary.TryGetValues({"xvalue", out x}, {"yvalue", out y}, 
    {"zvalue", out z});
if (foundAllEntries)
    ; // Do something with x, y, and z

ただし、出力を保持するオブジェクトに拡張メソッド参照を渡す方法がわかりません。これは非常に基本的なことのように思えます。

ローカル参照への参照をオブジェクトに格納するにはどうすればよいですか?

この質問は、TryGetValues 関数を実装する別の方法を求めているわけではないことに注意してください。これを「機能させる」方法はたくさんありますが、私が取ろうとしているアプローチほどクリーンなコードを生成する方法はありません。

4

2 に答える 2

9

これは非常に基本的なことのように思えます。

基本的ではないだけでなく、完全に不可能です。データ型をreforで修飾する方法はありませんout。これらの修飾子は、正式なメソッド パラメーターにのみ適用されます。つまり、「参照変数」や「出力変数」のようなものはありません。言語には「参照パラメーター」と「出力パラメーター」しかありません。

さらに、可変長の引数リスト (つまり、そのparams部分) の一部として出力または参照パラメーターを渡すことはできないため、その方法も機能しません。

これを「機能させる」方法はたくさんありますが、私が取ろうとしているアプローチほどクリーンなコードを生成する方法はありません。

不思議なことに、上記は、実装しようとしているスキームを実装できないという意味ではなく、Proxy Design Patternを適用すると、元のコードとほぼ同じくらいきれいなコードが残ります。トリックは、次のように、メソッド呼び出しをチェーンし、結果に暗黙の変換演算子を提供することです。

class MyMap {
    internal IDictionary<string,string> dict = ...
    public ItemGetterResult TryGetValues {
        get {
            return new ItemGetterResult(this, true);
        }
    }
}

class ItemGetterResult {
    private readonly MyMap map;
    private bool IsSuccessful {get;set;}
    internal ItemGetterResult(MyMap theMap, bool successFlag) {
        map = theMap;
        IsSuccessful = successFlag;
    }
    public static implicit operator bool(ItemGetterResult r) {
        return r.IsSuccessful;
    }
    public ItemGetterResult Get(string key, out string val) {
        return new ItemGetterResult(
            map
        ,   this.IsSuccessful && map.dict.TryGetValue(key, out val)
        );
    }
}

呼び出しは次のようになります。

bool foundAllEntries = myDictionary.TryGetValues
    .Get("xvalue", out x)
    .Get("yvalue", out y)
    .Get("zvalue", out z);
于 2014-12-31T22:30:47.260 に答える
0

可変Reference型を作成できます。

public class Reference<T>
{
    public T Value;
}

/* declaration */
bool TryGetValues(
    this Dictionary<K,V> dict,
    params Tuple<K, Reference<V>>[] requests)

/* call site */
var x = new Reference<string>();
var y = new Reference<string>();
var z = new Reference<string>();
bool foundAllEntries = myDictionary.TryGetValues(
    Tuple.Create("xvalue", x),
    Tuple.Create("yvalue", y), 
    Tuple.Create("zvalue", z));
于 2014-12-31T22:38:14.710 に答える