开发者

Generic Method to fill properties?How do you do it in .net 2.0?

I have 2 classes Customer an开发者_开发技巧d Person(share exactly the same properties and these properties should be filled in by a request

I would like to write a generic method like

    //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)?

Edit

I have no control over these classes. I just need to fill the properties and I was wondering if I could write a generic method rather than 2 specific ones.


Given the requirements, your options are somewhat limited. If you don't want to make use of the dynamic keyword (due to .NET version or whatever), you could do this old-style and use reflection. A possible implementation of that follows:

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;
}

Optionally, you could remove the where T : new() and replace the instantiation code with something like this:

T t = (T)Activator.CreateInstance(typeof(T));


+1 for CodeInChaos.

You should put the responsibility for reading properties from Request with the classes that have the properties. The best way would be to have either a base class or an interface that provides you with, let's say, a FillProperties method that takes a Request. Then put a restriction on T for your method that specifies the base class or interface and call T.FillProperties(request).


If you can't fix the design, I'd use duck typing instead. C# 4 has the dynamic keyword. You'll lose type safety, and refactoring support, but at least you don't repeat yourself.

public static void FillPropertiesOfCustomerOrPerson(dynamic person, Request request)
{
  person.Name=request.Name;
  person.Surname=request.Surname;
}


Have Person and Customer either inherit from a base class (e.g. Customer : Person) or implement a common interface. You can then just have your method accept the base type instead:

public static Person FillPropertiesOfPerson(Request request)
{
    Person returnValue = new Person();

    returnValue.Name = request.Name;
    // etc...

    return Person;
}

Note that if Person and Customer are partial classes (for example the proxy classes generated when you consume a web service) then you can use a partial-ness of these classes to do this:

// 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 { }

This will only work if Person and Customer declare exactly the same properties (and are partial classes obviously!), however if there are some slight mismatches then you can use your partial definition to do some "fudging."

Failing that the only method I'm aware of is to use reflection to set the properties, however this isn't typesafe, would incur some performance penalties and is all round not a great idea (I'd probably rather write two identical methods than resort to reflection for something like this).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜