2

オブジェクトから値を返していEntityます。Stringタイプされているものとそうでないものがあります。今、私は次のように簡単な解決策を実行しました。

private String GetStringValue(Entity entity, String attribute, String substitute = "")
{
  if(entity.Contains(attribute)
    return entity[attribute] as String;
  return substitute;
}

private String GetIntValue(Entity entity, String attribute, int substitute = 0)
{
  if(entity.Contains(attribute)
    return entity[attribute] as int;
  return substitute;
}

次に、ジェネリック型付けの構文 ( のようなもの) があることを思い出しました<TypeX>。ただし、私の質問は、既存のコードの変更を開始するポイントがあるかどうかです。メソッドのシグネチャを 2 か所 (戻り値の型と置換型) で変更する必要がありますが、メソッド内でも複雑なコーディングを行う必要があるのではないかと心配しています。

一方で、考えられるすべての型を処理する良い方法があると思います (そして、文字列と整数以外のものを扱うことになる予感があります。

4

6 に答える 6

2

ジェネリック パラメータも追加する必要があるため、メソッドのシグネチャを3か所で変更する必要があります。

private T GetValue<T>(Entity entity, String attribute, T substitute)

メソッド内では、複雑なコーディングはまったく必要ありません。stringまたはの現在の出現をintそれぞれ に置き換えるTだけで十分です。as(演算子は、参照型に制限する場合にのみ適用できることに注意してください。参照型は値型Tであるため、おそらく実行したくないでしょうint)。

この方法には、欠点と考えられる 2 つの問題があることに注意してください。

  • このジェネリック メソッドは「可能なすべての型」をサポートしますが、不可能な型もサポートします (ユーザーは に対して好きな型を自由に指定でき、 と の両方をサポートしながらT制限する方法はありません。Tstringint
  • 各タイプに任意のデフォルトの代替値を指定することはできません。できることはsubstitute、 、つまりのデフォルト値を宣言することですdefault(T)が、少なくともstring、それは空の文字列ではなくnull.
于 2013-02-08T08:30:31.740 に答える
1

あなたは正しい「何か」が一般的な方法です。そこでジェネリックメソッドをチェックしてください。 次の方法は、あなたの目的に適しています。

   private  static T GetValue<T>(Entity entity, string attribute, T defaultValue)
        {
            if (!entity.Contains(attribute))
                return defaultValue;

            return  (T)entity[attribute];
        }

編集: w0lf のコメントに従って更新されました。

于 2013-02-08T08:29:10.490 に答える
1

メソッドのシグネチャを変更したくない場合は、ジェネリック関数を記述して、これらの非ジェネリック バージョンすべてから呼び出すことができます。

private String GetStringValue(...){
    return GetValue<String>(...);
}

ところで、ジェネリックメソッドを探しています

たとえば(msdnから)

static void Swap<T>(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

...

Swap<int>(ref a, ref b);

あるいは単に

Swap(ref a, ref b); //type int is infered based on type of arguements and method signature
于 2013-02-08T08:27:51.150 に答える
1

は何のクラスEntityですか?それがカスタムクラスであると仮定して、それもジェネリックにすると、これは機能します:

private T Get<T>(Entity<T> entity, T attribute, T substitute = default(T))
{
    if (entity.Contains(attribute))
        return entity[attribute];
    return substitute;
}

次の方法で値を取得できます。

var entity = new Entity<string>();
string val = Get<string>(entity, "attr", "subst");
于 2013-02-08T08:33:31.367 に答える
0

Entity<T>クラスを定義する必要があります。

public class Entity<T>
{
    // TODO: implement
    public T this[string i] { get; set; }

    // TODO: implement
    internal bool Contains(string attribute)
    {
        return true;
    }
    // TODO: implement
    // other properties and methods       
}

そして、あなたは一般的な方法を使うかもしれません:

private T GetStringValue<T>(Entity<T> entity, String attribute, T substitute = default(T))
{
    if (entity.Contains(attribute))
        return entity[attribute];
    return substitute;
}
于 2013-02-08T08:40:07.810 に答える
0

メソッド内のコードを一般化できる場合は、一般的な方法で使用することを絶対にお勧めします。これにより、クラスが小さくなり、読みやすくなり、要件が変更された場合に 1 つのメソッドを変更するだけで済みます。あなたのメソッドは、簡単にジェネリックにできるようです。

private T GetIntValue<T>(Entity entity, String attribute, T substitute = default(T))
{
    if(entity.Contains(attribute))
        return (T)entity[attribute];
    return substitute;
}

実行するロジックがさらにある場合は、さまざまなタイプの関数を含む辞書を使用することもできます。

private IDictionary<Type, Func<Entity, string, object>> actions;

private void InitActions()
{
    actions = new Dictionary<Type, Func<Entity, string, object>>
        {
            {
                typeof (string), (entity, attribute) =>
                    {
                        // this could be your custom code for string
                        return entity[attribute];
                    }
            },
            {
                typeof (int), (entity, attribute) =>
                    {
                        // this could be your custom code for int
                        return entity[attribute];
                    }
            }
        };
}

private T GetIntValue<T>(Entity entity, String attribute, T substitute = default(T))
{
    if (entity.Contains(attribute) && actions.ContainsKey(typeof (T)))
    {
        Func<Entity, string, object> action = actions[typeof (T)];
        return (T)action(entity, attribute);
    }
    return substitute;
}
于 2013-02-08T08:41:50.813 に答える