C# 填充属性的通用方法?如何在.NET2.0中完成?
我有两个类Customer和Person(共享完全相同的属性,这些属性应通过请求填写) 我想写一个通用的方法,比如C# 填充属性的通用方法?如何在.NET2.0中完成?,c#,C#,我有两个类Customer和Person(共享完全相同的属性,这些属性应通过请求填写) 我想写一个通用的方法,比如 //Usage Customer myCustomer =CreateCustomerOrPerson<Customer>(myRequest) //Usage Person myPerson =CreateCustomerOrPerson<Person>(myRequest) public static T FillProperti
//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)?
//用法客户myCustomer=CreateCustomerOrPerson(myRequest)
//使用人myPerson=CreateCustomerPerson(myRequest)
公共静态T FillPropertiesOffCustomerPerson(请求)
{
//我不知道如何填充属性。
//T a=默认值(T);
//a、 Name=request.Name;
//a、 姓氏=请求。姓氏;
//如果(a是客户)
//{
//?
/// }
返回(T)a;
}
您将如何编写此通用方法以避免使用两种方法(一种用于客户,另一种用于个人)?
编辑
我无法控制这些类。我只需要填充属性,我想知道我是否可以编写一个通用方法而不是两个特定方法。拥有
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
声明完全相同的属性(显然是分部类!)时才有效,但是如果存在一些轻微的不匹配,则可以使用分部定义进行一些“捏造”
如果不能做到这一点,我所知道的唯一方法就是使用反射来设置属性,但是这不是类型安全的,会导致一些性能损失,而且这并不是一个好主意(我可能宁愿编写两个相同的方法,也不愿为类似的事情使用反射)。+1用于CodeInChaos
您应该将从请求读取属性的责任与具有这些属性的类放在一起。
最好的方法是使用一个基类或一个接口,为您提供接受请求的FillProperties方法。然后对指定基类或接口的方法的T设置限制,并调用T.FillProperties(请求).如果您无法修复设计,我会使用duck类型。C#4具有
动态
关键字。您将失去类型安全性和重构支持,但至少您不会重复自己
public static void FillPropertiesOfCustomerOrPerson(dynamic person, Request request)
{
person.Name=request.Name;
person.Surname=request.Surname;
}
考虑到这些要求,您的选项有些有限。如果您不想使用
动态
关键字(由于.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;
}
我的印象是,问题在于你的类设计。为什么两个类在不共享基类或接口的情况下具有相同/非常相似的属性?除了考虑基类或使用接口外,你还可以考虑组合,例如员工有联系信息。我无法控制这些类。我只需要填写属性,我想知道我是否可以编写一个通用方法,而不是两个特定的方法。感谢您的帮助和回复。不幸的是,我正在使用.net 2.0进行一个项目。您是说我唯一的选择是使用反射吗?@user231465在2.0中,您肯定无法使用
动态
。我想知道甚至有多少反射已更改。请查看反射解决方案是否已编译。或者,编写两个方法以避免使用反射:)。谢谢,但无法添加接口,因为我没有控制超类
T t = (T)Activator.CreateInstance(typeof(T));