将FieldName作为参数传递

Kir*_*ein 4 c# reflection anonymous-function

我不太确定我正在尝试做什么被称为,所以我很难找到谷歌的任何线索.

我有几个具有相同逻辑的方法,唯一不同的是它们在对象上使用的属性.

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;
}
Run Code Online (Sandbox Code Playgroud)

而不是Foo我想要的三个单独的方法,具有看起来更像的签名

public int X(Bar bar, ??? x)
{
   return bar.x * 2;
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?

BFr*_*ree 14

我第一次误读了这个问题,我的不好.

你可以用Reflection做到这一点:

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

然后,你这样称呼它:

Method(bar,"A");
Run Code Online (Sandbox Code Playgroud)

刚刚注意到在你的例子中,Bar中的3个变量是公共实例变量.我假设您刚刚为您的样本做了这个,但如果您的真实课程实际上是这种情况,请使用Rex M的方法.

  • 虽然这是可能的,但它可能导致运行时错误,因为编译器无法检查传递的属性是否存在.我会考虑改变设计. (6认同)

THX*_*138 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;
}
Run Code Online (Sandbox Code Playgroud)