Calling a property or method using an attribute name

Say I have a class that looks like this:

public class CallByAttribute { [CodeName("Foo")] public string MyProperty { get; set; } [CodeName("Bar")] public string MyMethod(int someParameter) { return myDictionary[someParameter]; } } 

How can I name these two properties or methods using CodeName instead of the name of the property or method?

+4
source share
2 answers

Method 1:

 public static TOutput GetPropertyByCodeName<TOutput>(this object obj, string codeName) { var property = obj.GetType() .GetProperties() .Where(p => p.IsDefined(typeof(CodeNameAttribute), false)) .Single(p => ((CodeNameAttribute)(p.GetCustomAttributes(typeof(CodeNameAttribute), false).First())).Name == codeName); return (TOutput)property.GetValue(obj, null); } 

Note. This will be issued if there is no property with the specified codeName or if several properties have the same codeName .

Using:

 CallByAttribute obj= ... string myProperty = obj.GetPropertyByCodeName<string>("Foo"); 

Method 2:

If you are in C # 4, you can write your own System.Dynamic.DynamicObject , which can route dynamic calls to the right member.

This will allow for a cleaner syntax. For example, you should be able to accomplish something that allows you to:

 CallByAttribute obj= ... dynamic objectByCodeName = new ObjectByCodeName(obj); objectByCodeName.Foo = "8"; objectByCodeName.Bar(); 
+5
source

Here are some fully functional codes, including optional arguments:

  private static string Call(object callByAttribute, string name, object[] args) { PropertyInfo prop = callByAttribute.GetType().GetProperties() .Where(p => p.IsDefined(typeof(CodeNameAttribute), false)) .SingleOrDefault(p => ((CodeNameAttribute)(p.GetCustomAttributes(typeof(CodeNameAttribute), false)).First()).Name == name); if (prop != null) return (string)callByAttribute.GetType().InvokeMember(prop.Name, BindingFlags.GetProperty, null, callByAttribute, null); MethodInfo method = callByAttribute.GetType().GetMethods() .Where(p => p.IsDefined(typeof(CodeNameAttribute), false)) .SingleOrDefault(p => ((CodeNameAttribute)(p.GetCustomAttributes(typeof(CodeNameAttribute), false)).First()).Name == name); if (method != null) return (string)callByAttribute.GetType().InvokeMember(method.Name, BindingFlags.InvokeMethod, null, callByAttribute, args); throw new Exception("method/getter not found"); } private static string Call(object callByAttribute, string name) { return Call(callByAttribute, name, null); } 

This can be used in the full program, for example:

 using System; using System.Linq; using System.Reflection; namespace ConsoleApplication1 { public class CallByAttribute { [CodeName("Foo")] public string MyProperty { get; set; } [CodeName("Bar")] public string MyMethod(int someParameter) { return "blah" + someParameter; } } public class CodeNameAttribute : Attribute { private readonly string name; public CodeNameAttribute(string name) { this.name = name; } public string Name { get { return name; } } } class Program { static void Main(string[] args) { CallByAttribute callByAttribute = new CallByAttribute(); callByAttribute.MyProperty = "hi"; Console.WriteLine(Call(callByAttribute, "Bar", new object[] {1})); Console.WriteLine(Call(callByAttribute, "Foo")); } private static string Call(object callByAttribute, string name) { return Call(callByAttribute, name, null); } private static string Call(object callByAttribute, string name, object[] args) { PropertyInfo prop = callByAttribute.GetType().GetProperties() .Where(p => p.IsDefined(typeof(CodeNameAttribute), false)) .SingleOrDefault(p => ((CodeNameAttribute)(p.GetCustomAttributes(typeof(CodeNameAttribute), false)).First()).Name == name); if (prop != null) return (string)callByAttribute.GetType().InvokeMember(prop.Name, BindingFlags.GetProperty, null, callByAttribute, null); MethodInfo method = callByAttribute.GetType().GetMethods() .Where(p => p.IsDefined(typeof(CodeNameAttribute), false)) .SingleOrDefault(p => ((CodeNameAttribute)(p.GetCustomAttributes(typeof(CodeNameAttribute), false)).First()).Name == name); if (method != null) return (string)callByAttribute.GetType().InvokeMember(method.Name, BindingFlags.InvokeMethod, null, callByAttribute, args); throw new Exception("method/getter not found"); } } } 
+3
source

All Articles