我不太确定我打算做什么,所以我很难找到谷歌的任何线索。
我有几个方法具有相同的逻辑,唯一不同的是它们在对象上使用的属性。
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;
}
而不是Foo
中的三个单独的方法,我想要一个,看起来更像是
public int X(Bar bar, ??? x)
{
return bar.x * 2;
}
这可能吗?
答案 0 :(得分: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;
}
然后,你这样称呼它:
Method(bar,"A");
注意,在您的示例中,Bar中的3个变量是公共实例变量。我假设你刚刚为你的样本做了这个,但如果你的真实课程实际上是这样,那就用Rex M的方法。
答案 1 :(得分:10)
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;
}
答案 2 :(得分:3)
我会考虑使用匿名代表来获取您的价值。
public int X(Bar bar, Func<Bar,int> getIt)
{
return getIt(bar) * 2;
}
然后称之为:
var x = X(mybar, x=>x.A);
答案 3 :(得分:0)
您可以使用反射实现此目的。它会产生一些性能影响
答案 4 :(得分:0)
您可以使用PropertyInfo类通过反射检索所需的属性:https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6099345.html
答案 5 :(得分:0)
public int X(Bar bar, string target)
{
object value = bar.GetType().GetField(target, BindingFlags.Public | BindingFlags.Instance).GetValue(bar);
return (int)value * 2;
}
答案 6 :(得分: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);
答案 7 :(得分:0)
使用FieldInfo
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public;
FieldInfo field = typeof(Bar).GetField("A", flags);
field.SetValue(..)来设置值。
答案 8 :(得分:0)
您可以使用扩展方法..对于您发布的示例..但我想您的示例只是一些更复杂代码的简化版本。
public static class IntExt
{
//use Bar.A.Double();
public int Double(this int value)
{
return value * 2;
}
}
答案 9 :(得分: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);
答案 10 :(得分: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
}
}
我对您的示例进行了一些更改,这是不现实的(如@JonasElfström所说,在这种情况下,您可以简单地传递值)。这表明您可以更改字段的值。