C# 填充属性的通用方法?如何在.NET2.0中完成?

C# 填充属性的通用方法?如何在.NET2.0中完成?,c#,C#,我有两个类Customer和Person(共享完全相同的属性,这些属性应通过请求填写) 我想写一个通用的方法,比如 //Usage Customer myCustomer =CreateCustomerOrPerson<Customer>(myRequest) //Usage Person myPerson =CreateCustomerOrPerson<Person>(myRequest) public static T FillProperti

我有两个类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)?
//用法客户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));