6

私が何をしようとしているのかよくわからないので、グーグルから手がかりを見つけるのに苦労しています。

同じロジックを持つメソッドがいくつかありますが、唯一の違いは、オブジェクトで使用しているプロパティです。

class Foo
{
   public int A(Bar bar)
   {
      return bar.A * 2;
   }

   public int B(Bar bar)
   {
      return bar.B * 2;
   }

   public int C(Bar bar)
   {
      return bar.C * 2;
   }
}

class Bar
{
   public int A;
   public int B;
   public int C;
}

I want oneの 3 つの個別のメソッドの代わりに、Fooより類似したシグネチャを使用します。

public int X(Bar bar, ??? x)
{
   return bar.x * 2;
}

これは可能ですか?

4

11 に答える 11

17

初めて質問を読み間違えました、悪いです。

リフレクションでこれを行うことができます:

public int Method(Bar bar, string propertyName)
{
   var prop = typeof(Bar).GetProperty(propertyName);
   int value = (int)prop.GetValue(bar,null);
   return value * 2;
}

次に、次のように呼び出します。

Method(bar,"A");

あなたの例では、 Bar の 3 つの変数が public インスタンス変数であることに気付きました。サンプルに対してこれを行っただけだと思いますが、実際のクラスでこれが実際に当てはまる場合は、Rex M のアプローチを使用してください。

于 2009-05-27T13:49:24.637 に答える
11
internal class Program {
    private static void Main(string[] args) {
        var bar = new Bar {A = 1, B = 2, C = 3};
        Console.WriteLine(new Foo().X(bar, it => it.A));
        Console.WriteLine(new Foo().X(bar, it => it.B));

        // or introduce a "constant" somewhere
        Func<Bar, int> cFieldSelector = it => it.C;
        Console.WriteLine(new Foo().X(bar, cFieldSelector));
    }
}

internal class Foo {
    // Instead of using a field by name, give it a method to select field you want.
    public int X(Bar bar, Func<Bar, int> fieldSelector) {
        return fieldSelector(bar) * 2;
    }

    public int A(Bar bar) {
        return bar.A * 2;
    }

    public int B(Bar bar) {
        return bar.B * 2;
    }

    public int C(Bar bar) {
        return bar.C * 2;
    }
}

internal class Bar {
    public int A;
    public int B;
    public int C;
}
于 2009-05-27T14:02:26.060 に答える
3

代わりに匿名デリゲートを使用して値を取得することを検討します。

public int X(Bar bar, Func<Bar,int> getIt)
{
   return getIt(bar) * 2;
}

次に、次のように呼び出します。

var x = X(mybar, x=>x.A);
于 2009-05-27T14:06:36.880 に答える
0

あなたが投稿した例では、拡張メソッドを使用できます..しかし、あなたの例は、より複雑なコードの単純化されたバージョンにすぎないと思います。

public static class IntExt
{
    //use Bar.A.Double();
    public int Double(this int value)
    {
        return value * 2;
    }
}
于 2009-05-27T14:04:09.380 に答える
0

列挙を使用して関数に渡して、使用するものを決定してみませんか? 右に一歩を踏み出すために、反射は世界の西に向かっているようです...

class Foo
{
   public enum BarChoice { a,b,c };
   public int x(Bar bar, BarChoice bc)
   {
     switch(bc) 
     {
       case a:
         return bar.A * 2;
       case b:
         return bar.B * 2;
       case c:
         return bar.C * 2;
     }
     return int.MinValue;
   }
}

次に、あなたの呼び出しは

 Foo f = new foo();
 Bar b = new Bar();
 f.x(b, Foo.BarChoice.a);
 f.x(b, Foo.BarChoice.b);
 f.x(b, Foo.BarChoice.c);
于 2009-05-27T14:06:07.520 に答える
0

これは、リフレクションを使用して実現できます。パフォーマンスに多少の影響があります

于 2009-05-27T13:52:07.877 に答える
0

PropertyInfo クラスを使用して、リフレクション経由で目的のプロパティを取得できます: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6099345.html

于 2009-05-27T13:53:21.290 に答える
0

ref次のキーワードを使用できます。

class Foo
{
    public void A(ref int fieldRef)
    {
        fieldRef *= 2;
    }
}

class Bar
{
    public int A;
    public int B;
    public int C;
}

class Program
{
    static void Main(string[] args)
    {
        var bar = new Bar { A = 1, B = 2, C = 3 };
        var foo = new Foo();
        foo.A(ref bar.A);
        foo.A(ref bar.B);
        foo.A(ref bar.C);

        Console.WriteLine(bar.A); // 2
        Console.WriteLine(bar.B); // 4
        Console.WriteLine(bar.C); // 6
    }
}

現実的ではない例を少し変更しました(@Jonas Elfströmが言ったように、この場合は値を渡すだけです)。これは、フィールドの値を変更できることを示しています。

于 2020-08-19T18:00:59.360 に答える
0
public int X(Bar bar, string target)
{
    object value = bar.GetType().GetField(target, BindingFlags.Public | BindingFlags.Instance).GetValue(bar);
    return (int)value * 2;
}
于 2009-05-27T13:56:56.213 に答える
0

反射を使用してみてください。効果を実現するための簡単なコードを次に示します。

using System.Reflection;    

public int X(Bar bar, FieldInfo x)
{
    return (int)x.GetValue(bar) * 2;
}

これで、最初に Bar のいずれかのフィールドの FieldInfo を取得して X を呼び出すことができます。

Bar b = new Bar();
b.A = 20;
b.B = 30;
b.C = 40;

FieldInfo fieldA = typeof(Bar).GetField("A");
int result = X(b, fieldA);
于 2009-05-27T13:58:00.500 に答える
0

FieldInfo を使用する

BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
FieldInfo field = typeof(Bar).GetField("A", flags);

field.SetValue(..) を使用して値を設定します。

于 2009-05-27T13:59:02.370 に答える