I have a three class which is having following properties
Class A
{
public int CustID { get; set; }
public string Name{ get; set; }
}
Class B
{
public int CustID { get; set; }
public string Age { get; set; }
}
I created one generic method which accepts all these classes.
public void ProceesData<T>(IList<T> param1, string date1)
{
Parallel.ForEach(T, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
GetDetails(CustID );
RaiseRequest<T>(param1);
});
}
CustID property is present in Both classes(ie in Class A& Class B).How can i access CustID property in this generic method ? Can anyone help on this
Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.
To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular . NET types.
A generic type is declared by specifying a type parameter in an angle brackets after a type name, e.g. TypeName<T> where T is a type parameter.
A generic class or structure can contain nongeneric procedures, and a nongeneric class, structure, or module can contain generic procedures. A generic procedure can use its type parameters in its normal parameter list, in its return type if it has one, and in its procedure code.
Another possibility would be to use System.Reflection
.
Get the PropertyInfo
from the given type T
with the name of the property
with that PropertyInfo
you can use GetValue
to get the corresponding value of that property.
Here is a small test programm to exemplify this:
public class ClassA
{
public int CustID { get; set; }
public string Name { get; set; }
}
public class ClassB
{
public int CustID { get; set; }
public string Age { get; set; }
}
public static void ProceesData<T>(IList<T> param1, string date1)
{
Parallel.ForEach(param1, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
var value = typeof(T).GetProperty("CustID").GetValue(currentItem);
Console.WriteLine("Value: " + value);
});
}
public static void Main(string[] args)
{
List<ClassA> test = new List<ClassA>();
test.Add(new ClassA { CustID = 123 });
test.Add(new ClassA { CustID = 223 });
test.Add(new ClassA { CustID = 323 });
ProceesData<ClassA>(test, "test");
}
EDIT
To make it a little more universal you could just pass the parameter name into the method:
public static void ProceesData<T>(IList<T> param1, string date1, string parameter)
{
Parallel.ForEach(param1, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
var value = typeof(T).GetProperty(parameter).GetValue(currentItem);
Console.WriteLine("Value: " + value);
});
}
Now you can decide what parameter you want to use:
ProceesData<ClassA>(test, "test", "Name");
or
ProceesData<ClassB>(test, "test", "Age");
As suggested by Gusman you could speed up a little by getting the PropertyInfo
just once before the loop:
PropertyInfo pi = typeof(T).GetProperty(parameter);
Parallel.ForEach(param1, (currentItem) =>
{
// I want to aceess CustID property of param1 and pass that value to another function
var value = pi.GetValue(currentItem);
Console.WriteLine("Value: " + value);
});
EDIT
Apparently performance seems to be an issue for you. So here is a comparison. You can try it on your own if you have a minute to wait. If we measure on the access time of the property:
public static void ProceesDataD<T>(IList<T> param1, string date1)
{
Parallel.ForEach(param1, (currentItem) =>
{
dynamic obj = currentItem;
int custId = obj.CustID;
});
}
public static void ProceesData<T>(IList<T> param1, string date1) where T : ICust
{
Parallel.ForEach(param1, (currentItem) =>
{
var value = currentItem.CustID;
});
}
public static void ProceesData<T>(IList<T> param1, string date1, string parameter)
{
PropertyInfo pi = typeof(T).GetProperty(parameter);
Parallel.ForEach(param1, (currentItem) =>
{
var value = pi.GetValue(currentItem);
});
}
public static void Main(string[] args)
{
List<ClassA> test = new List<ClassA>();
List<A> testA = new List<A>();
Stopwatch st = new Stopwatch();
for (int i = 0; i < 10000; i++)
{
test.Add(new ClassA { CustID = 123, Name = "Me" });
testA.Add(new A { CustID = 123, Name = "Me" });
}
st.Start();
ProceesData<ClassA>(test, "test", "CustID");
st.Stop();
Console.WriteLine("Reflection: " + st.ElapsedMilliseconds);
st.Restart();
ProceesData<A>(testA, "test");
st.Stop();
Console.WriteLine("Interface: " + st.ElapsedMilliseconds);
st.Restart();
ProceesDataD<ClassA>(test, "test");
st.Stop();
Console.WriteLine("Dynamic: " + st.ElapsedMilliseconds);
}
Disclaimer: use the code passages to measure the time only one at the time. Do not run the program as it is but each single test on it's own.
Introduce interface:
interface ICust
{
public int CustID { get;}
}
class A : ICust
{
public int CustID { get; set; }
public string Name{ get; set; }
}
class B : ICust
{
public int CustID { get; set; }
public string Age { get; set; }
}
public void ProceesData<T>(IList<T> param1, string date1) where T : ICust
{
Parallel.ForEach(param1, (currentItem) =>
{
GetDetails(currentItem.CustID)
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With