[英]Runtime assignment of data based on target class type
I have 5 different classes with same properties but with a different namespace.我有 5 个具有相同属性但具有不同命名空间的不同类。
For example:例如:
MyNameSpace1.Class1 - FirstName, LastName, Age
MyNameSpace2.Class2 - FirstName, LastName, Age
and so on等等
. .
All the classes have the same properties - for say, FirstName, LastName, Age etc.所有类都具有相同的属性 - 例如,名字、姓氏、年龄等。
private void AssignData(int order, string firstName, string lastName)
{
if(order==1)
{
var result=new MyNameSpace1.Class1();
result.FirstName= firstName;
result.LastName=lastName;
}
if(order==2)
{
var result=new MyNameSpace2.Class2();
result.FirstName= firstName;
result.LastName=lastName;
}
}
Above, I have given just two properties, in my real example, there are multiple properties, that get assigned.上面,我只给出了两个属性,在我的真实示例中,有多个属性被分配。
I tried to simplify that as我试图将其简化为
private void AssignData(int order, string firstName, string lastName)
{
if(order==1)
{
var result= GetInstance<MyNameSpace1.Class1>();
result.FirstName=firstName;
result.LastName=lastName;
}
if(order==2)
{
var result= GetInstance<MyNameSpace2.Class2>();
result.FirstName=firstName; //repeated code , don’t want to use dynamic,
//as I will not know the compile time issues.
result.LastName=lastName;
}
}
Seems, I am repeating same code again, is there an option, where I will need to assign firstName, lastName directly just once and create runtime instance of the class?似乎,我再次重复相同的代码,是否有一个选项,我需要直接分配 firstName、lastName 一次并创建 class 的运行时实例?
private T GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
What i am trying to achieve is我想要实现的是
private void AssignData(int order, string firstName, string lastName)
{
var result; //this will not compile, object might, prefer not to use dynamic
if(order==1)
{
result= GetInstance<MyNameSpace1.Class1>();
}
if(order==2)
{
result= GetInstance<MyNameSpace2.Class2>();
}
result.FirstName=firstName;//just do assignments 1 time
result.LastName=lastName;
}
First and easiest option would be just using dynamic
type:第一个也是最简单的选择就是使用dynamic
类型:
class MyClass
{
public int MyProperty { get; set; }
}
private dynamic GetInstance<T>()
{
return Activator.CreateInstance<T>();
}
var instance = GetInstance<MyClass>();
instance.MyProperty = 5;
Console.WriteLine(instance.MyProperty);
so I would not recommend cause it is considered not very performant.所以我不推荐,因为它被认为不是很好。
Second option would using reflection like this:第二个选项将使用这样的反射:
var instance = GetInstance<MyClass>();
typeof(MyClass).GetProperty("MyProperty")
.GetSetMethod()
.Invoke(instance, new object[] { 5}); // sets MyProperty to 5
You can "cache" result of GetSetMethod
and reuse it, cause reflection is slow also.您可以“缓存” GetSetMethod
的结果并重用它,因为反射也很慢。
Last option is reflection + expression trees(where you can generate "whole" method to set all variables):最后一个选项是反射+表达式树(您可以在其中生成“整体”方法来设置所有变量):
var type = typeof(MyClass);
var method = type.GetProperty(nameof(MyClass.MyProperty)).GetSetMethod();
var cls = Expression.Parameter(typeof(MyClass));
var val = Expression.Parameter(typeof(int));
var call = Expression.Call(cls, method, val);
// this action should be cached
var act = Expression.Lambda<Action<MyClass, int>>(call, cls, val).Compile();
var instance = GetInstance<MyClass>();
act(instance, 5); // sets MyProperty to 5
An again do not forget to cache result of Expression.Lambda.Compile
for type.再次不要忘记缓存Expression.Lambda.Compile
类型的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.