2016-07-06
Code below will search for a given named property, field, or method inside a given object.
It will search in below order:
- Properties
- Fields
- Methods
It will continue to search until it finds a match that holds or returns (for methods) a non-null value.
E.g. If you searched for “Name” and if there is a property called Name that returns null then the code will continue looking for fields and methods.
SearchTillNotNull Parameter
If you set the parameter SearchTillNotNull to false then the method will return as soon as it finds a hit even if the resolved value is null.
Searching for methods
Code searches for a method with either the same name as the given SearchFor or a method name with “Get” and SearchFor phrase. (e.g. if SearchFor=”Name” then a methods “GetName”, “getName”, and “Name” will all qualify).
Parameters for methods
Code will only execute matching methods if either the method doesn’t require any parameters or the number of parameters given to the code is same as the number of parameters required by the particular method.
Notes:
- All searches are are case insensitive and uses OrdinalIgnoreCase string comparison.
- Uses reflection
- Implemented in C#.Net
- Tested to work on .Net framework 2.0 and above
Below is the code, you can also download the .cs file from here
using System; namespace CMRSoft.Reflection { class ObjectReader { /// <summary> /// Searches the given object until it finds a value for the given SearchFor string /// </summary> /// <param name="Obj">Object to search inside</param> /// <param name="SearchFor">Name of the value to look for</param> /// <param name="SearchTillNotNull">If set to true, will continue searching if it finds a match but received null value from the match</param> /// <returns>Found value or null</returns> public object GetValueFromObject(object Obj, string SearchFor, bool SearchTillNotNull = true, params object[] MethodParameters) { var t = Obj.GetType(); // check all properties foreach (var prop in t.GetProperties()) { if (prop.Name.Equals(SearchFor, StringComparison.OrdinalIgnoreCase)) { var tmp = prop.GetValue(Obj, null); if (tmp != null || !SearchTillNotNull) { return tmp; } } } // check all fields foreach (var fld in t.GetFields()) { if (fld.Name.Equals(SearchFor, StringComparison.OrdinalIgnoreCase)) { var tmp = fld.GetValue(Obj); if (tmp != null || !SearchTillNotNull) { return tmp; } } } // search methods foreach (var mtd in t.GetMethods()) { if (mtd.Name.Equals(SearchFor, StringComparison.OrdinalIgnoreCase) || mtd.Name.Equals("get" + SearchFor, StringComparison.OrdinalIgnoreCase)) { var parameters = mtd.GetParameters(); if (parameters.Length == 0 || (MethodParameters != null && parameters.Length == MethodParameters.Length)) { var tmp = mtd.Invoke(Obj, MethodParameters); if (tmp != null || !SearchTillNotNull) { return tmp; } } } } return null; } } }
Example use:
namespace CMRSoft.Reflection { class Program { static void Main(string[] args) { ObjectReader _r = new ObjectReader(); var testObj = new Test() { Value1 = 100, Value2=3 }; Console.WriteLine(_r.GetValueFromObject(testObj, "value1")); // outputs 100 Console.WriteLine(_r.GetValueFromObject(testObj, "pi", MethodParameters: 4)); // Notice the search phrase does not contain "get". The Object Reader looks for methods with get prefix to what's being searched for. // outputs 3.1416 Console.ReadLine(); } } class Test : ITest { public double Value1 { get; set; } public double Value2 { get; set; } public double getPi(int DecimalPlaces) { return Math.Round(Math.PI, DecimalPlaces); } } interface ITest { double getPi(int DecimalPlaces); } }
Please feel free to comment your suggestions.
Menol