Pass FieldName as a parameter

I'm not quite sure what I'm trying to do, it's called that, so I'm trying to find any clues from Google.

I have several methods with the same logic in them, the only thing that is different is the property that they use on the object.

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; } 

Instead of three separate methods in Foo I want one with a signature that looks more like

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

Is it possible?

+4
source share
10 answers
 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; } 
+8
source

I misunderstood the question for the first time, my bad.

You can do this with Reflection:

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

Then you call it like this:

 Method(bar,"A"); 

Just noticed that in your example, the three variables in Bar are public instance variables. I assume that you just did it for your sample, but if it is really so in your real class, use the Rex M approach.

+13
source

I would like to use an anonymous delegate to get your value.

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

Then name it like this:

 var x = X(mybar, x=>xA); 
+3
source

You can achieve this using reflection. It will have some effect on performance.

0
source

you can use the PropertyInfo class to retrieve the desired property through reflection: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6099345.html

0
source
 public int X(Bar bar, string target) { object value = bar.GetType().GetField(target, BindingFlags.Public | BindingFlags.Instance).GetValue(bar); return (int)value * 2; } 
0
source

Try using reflection. Here are some simple codes to achieve the effect.

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

Now you can call X by first getting the FieldInfo field for one of the fields in the panel.

 Bar b = new Bar(); bA = 20; bB = 30; bC = 40; FieldInfo fieldA = typeof(Bar).GetField("A"); int result = X(b, fieldA); 
0
source

Use FieldInfo

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

field.SetValue (..) to set the value.

0
source

you can use the extension method .. for the example you posted .. but I assume that your example is just a simplified version of more complex code.

 public static class IntExt { //use Bar.A.Double(); public int Double(this int value) { return value * 2; } } 
0
source

Why not use an enumeration and pass it to a function to determine which one to use? It seems like the reflection is looking west around the world to take a step to the right ...

 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; } } 

Then your call will be

  Foo f = new foo(); Bar b = new Bar(); fx(b, Foo.BarChoice.a); fx(b, Foo.BarChoice.b); fx(b, Foo.BarChoice.c); 
0
source

All Articles