填充属性的通用方法?如何在.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个特定的。

填充属性的通用方法?如何在.net 2.0中实现呢?

给定需求,您的选择有些有限。如果您不想使用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;
}

PersonCustomer从一个基类(例如Customer : Person)继承或实现一个公共接口。然后你可以让你的方法接受基类型:

public static Person FillPropertiesOfPerson(Request request)
{
    Person returnValue = new Person();
    returnValue.Name = request.Name;
    // etc...
    return Person;
}

请注意,如果PersonCustomer是部分类(例如,当您使用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 { }

这将只工作,如果PersonCustomer声明完全相同的属性(显然是部分类!),但是,如果有一些轻微的不匹配,那么你可以使用你的部分定义做一些"捏造"。"

如果失败,我所知道的唯一方法是使用反射来设置属性,但这不是类型安全的,会导致一些性能损失,并且总的来说不是一个好主意(我可能宁愿写两个相同的方法,而不是诉诸反射来实现这样的事情)。