Reputation: 109
I've been playing around with generics, and am trying to figure out how (if possible) I can use a single method across multiple classes by passing the object dynamically.
I have a couple of classes, Foo and Bar as per below:
[Serializable()]
public class Foo
{
private string m_Code;
private Bar m_Bar = new Bar();
public string Code
{
get { return m_Code; }
set { m_Code = value; }
}
public Bar Bar
{
get { return m_Bar; }
set { m_Bar = value; }
}
}
and
[Serializable()]
public class Bar
{
private string m_Name;
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
}
If I populate my class with some dummy data as such:
Foo.Code = "myFoo";
Foo.Bar.Name = "myBar";
I have a generic method to return a value from the class:
public static object getItem<T>(T obj, string _Value)
{
try
{
object _Resolved = null;
_Resolved = obj.GetType().GetProperty(_Value).GetValue(obj, null);
return _Resolved;
}
catch (Exception ex)
{
return null;
}
}
Calling my getItem method like below works fine.
string FooCode = Convert.ToString(getItem<Foo>(myFoo, "Code")) // returns "myFoo"
string BarName = Convert.ToString(getItem<Bar>(myFoo.Bar, "Name")) // returns "myBar"
What I am curious about is if there is a generic way of addressing my getItem method, by defining the object?
For example:
object myObject = Foo;
string FooCode = Convert.ToString(getItem<typeof(myObject)>(myObject, "Code")) // And this would returns "myFoo"
or:
object myObject = Bar;
string BarName = Convert.ToString(getItem<typeof(myObject)>(myObject, "Name")) // And this would returns "myBar"
Upvotes: 1
Views: 3052
Reputation: 17485
You can do like this.
string FooCode = Convert.ToString(getItem(myFoo, "Code")) // returns "myFoo"
string BarName = Convert.ToString(getItem(myFoo.Bar, "Name")) // returns "myBar"
It automatically infer type of object. If you want to call Generic method at runtime from object type then you have to create generic method using reflection. Following is the example.
public class Program
{
static void Main(string[] args)
{
Foo myFoo = new Foo();
myFoo.Bar = new Bar();
myFoo.Bar.Name = "Jinal";
myFoo.Code = "Ths is test";
// By Using infer
string FooCode = Convert.ToString(getItem(myFoo, "Code")); // returns "myFoo"
string BarName = Convert.ToString(getItem(myFoo.Bar, "Name"));
// Using Reflection
Type ex = typeof(Program);
MethodInfo mi = ex.GetMethod("getItem");
object foo = myFoo;
var methodgetItem = mi.MakeGenericMethod(foo.GetType());
string result = Convert.ToString(methodgetItem.Invoke(null, new object[]{foo , "Code"}));
object bar = myFoo.Bar;
var methodgetItem1 = mi.MakeGenericMethod(bar.GetType());
string result1 = Convert.ToString(methodgetItem1.Invoke(null, new object[] {bar , "Name" }));
Console.ReadLine();
}
public static object getItem<T>(T obj, string _Value)
{
try
{
object _Resolved = null;
_Resolved = obj.GetType().GetProperty(_Value).GetValue(obj, null);
return _Resolved;
}
catch (Exception ex)
{
return null;
}
}
}
Upvotes: 2
Reputation: 4465
In the getItem
method, you are not using the Type parameter T
.
For your specific question (where type of obj
is not known at compile time), you could simply define your method as follows -
public static object getItem(object obj, string _Value)
Upvotes: 0