填充属性的通用方法?如何在.net 2.0中实现呢?
本文关键字:net 实现 属性 填充 方法 | 更新日期: 2023-09-27 18:02:05
我有两个类Customer和Person(共享完全相同的属性,这些属性应该由请求填写
我想写一个像 这样的泛型方法 //Usage Customer myCustomer =CreateCustomerOrPerson<Customer>(myRequest)
//Usage Person myPerson =CreateCustomerOrPerson<Person>(myRequest)
public static T FillPropertiesOfCustomerOrPerson<T>(Request request)
{
//not sure how I would I do it to fill the properties.
// T a = default(T);
//a.Name=request.Name;
//a.Surname=request.Surname;
// if (a is Customer)
//{
//?
/// }
return (T)a;
}
How would you write this generic method to avoid having 2 methods (one for customer and one for person)?
编辑我无法控制这些类。我只需要填写属性,我想知道我是否可以写一个通用的方法,而不是2个特定的。
给定需求,您的选择有些有限。如果您不想使用dynamic
关键字(由于。net版本或其他原因),您可以使用这种老式方式并使用反射。一个可能的实现如下:
private const string PROP_NAME = "Name";
private const string PROP_SURNAME = "Surname";
public static T FillPropertiesOfCustomerOrPerson<T>(Request request)
where T : new()
{
if (typeof(T) != typeof(Person) && typeof(T) != typeof(Customer))
{
throw new Exception(
string.Format("{0} is not a supported type.", typeof(T).Name)
);
}
PropertyInfo name = typeof(T).GetProperty(PROP_NAME);
PropertyInfo surname = typeof(T).GetProperty(PROP_SURNAME);
T t = new T();
name.SetValue(t, request.Name, null);
surname.SetValue(t, request.Surname, null);
return t;
}
可选地,您可以删除where T : new()
并用以下内容替换实例化代码:
T t = (T)Activator.CreateInstance(typeof(T));
+1 for CodeInChaos.
你应该把从Request中读取属性的责任与拥有这些属性的类放在一起。最好的方法是有一个基类或一个接口,它为你提供,比方说,一个接受Request的FillProperties方法。然后为指定基类或接口的方法对T施加限制,并调用T. fillproperties(请求)。
如果你不能修复设计,我会使用duck typing代替。c# 4有dynamic
关键字。您将失去类型安全性和重构支持,但至少您不必重复自己。
public static void FillPropertiesOfCustomerOrPerson(dynamic person, Request request)
{
person.Name=request.Name;
person.Surname=request.Surname;
}
让Person
和Customer
从一个基类(例如Customer : Person
)继承或实现一个公共接口。然后你可以让你的方法接受基类型:
public static Person FillPropertiesOfPerson(Request request)
{
Person returnValue = new Person();
returnValue.Name = request.Name;
// etc...
return Person;
}
请注意,如果Person
和Customer
是部分类(例如,当您使用web服务时生成的代理类),那么您可以使用这些类的部分性来执行此操作:
// Define your interface to match the properties which are common to both types
interface IPerson
{
string Name
{
get;
set;
}
}
// Then use partial declarations like this (must be in the same namespace as the generated classes)
public partial class Person : IPerson { }
public partial class Customer : IPerson { }
这将只工作,如果Person
和Customer
声明完全相同的属性(显然是部分类!),但是,如果有一些轻微的不匹配,那么你可以使用你的部分定义做一些"捏造"。"
如果失败,我所知道的唯一方法是使用反射来设置属性,但这不是类型安全的,会导致一些性能损失,并且总的来说不是一个好主意(我可能宁愿写两个相同的方法,而不是诉诸反射来实现这样的事情)。