4

我有一个功能如下。

private IList<ContactList> getEmptyRow()
{
    var _ContactList = new List<ContactList>();
    _ContactList.Add(new ContactList()
    {
        Email = string.Empty,
        Name = string.Empty
    });

    return _ContactList;
}

我想把我的班级ContactList改成

private IList<T> getEmptyRow() {  ..... T.Add(new T()....

这可能吗 ?如何 ?
每一个建议都将不胜感激。

4

2 回答 2

6

大概是这样的?

public interface IPerson
{ 
    string Email {get;set;}
    string Name {get;set;}
}

public class SomeClass
{
    private IList<T> getEmptyRow<T>() where T : IPerson, new()
    {
        var t = new List<T>();
        t.Add(new T()
        {
            Email = string.Empty,
            Name = string.Empty
        });

        return t;
    }
}

您需要一个接口或基类,以便您可以设置公共属性EmailName并且您需要new()约束,以便您可以使用默认构造函数。

于 2012-10-08T02:02:48.310 回答
4

有点晚了,因为您已经接受了答案,但作为替代方案,特别是如果new()不是一个选项,您可以使用预定义的构造函数/初始化语法设置提供程序,这应该会给您一些灵活性:

public static class EmptyRowProvider
{
    private static Dictionary<Type, object> TypeCreators = new Dictionary<Type, object>();

    public static void RegisterType<T>(Func<T> emptyTypeCreator)
    {
        TypeCreators.Add(typeof(T), emptyTypeCreator);
    }

    public static IList<T> GetEmptyRow<T>()
    {
        object typeCreatorUntyped;
        if (!TypeCreators.TryGetValue(typeof(T), out typeCreatorUntyped))
            throw new Exception("Type " + typeof(T).FullName + " not registered!");

        Func<T> typeCreator = (Func<T>)typeCreatorUntyped;

        IList<T> emptyRow = new List<T>();
        emptyRow.Add(typeCreator());
        return emptyRow;
    }
}

在应用程序初始化期间的某个地方,您将注册类型及其工厂方法。稍后,您只需按将运行该方法的类型进行调用:

EmptyRowProvider.RegisterType(() => new ContactList() { Email = String.Empty, Name = String.Empty });


var emptyRow = EmptyRowProvider.GetEmptyRow<ContactList>();

Console.WriteLine(emptyRow.Count); //1
Console.WriteLine(emptyRow[0].Email == String.Empty); //true
Console.WriteLine(emptyRow[0].Name == String.Empty); //true

假设您有一个没有无参数构造函数的类型,或者您后来决定更改它的初始化方式。稍后说您ContactList使用了不同的构造函数:

public ContactList(string email, string name, bool isPrivate)
{
    //initialize data here  
}

然后您的新代码用法可能如下所示:

EmptyRowProvider.RegisterType(() => new ContactList(String.Empty, String.Empty, true));


var emptyRow = EmptyRowProvider.GetEmptyRow<ContactList>();

Console.WriteLine(emptyRow.Count); //1
Console.WriteLine(emptyRow[0].Email == String.Empty); //true
Console.WriteLine(emptyRow[0].Name == String.Empty); //true
Console.WriteLine(emptyRow[0].IsPrivate == true); //true

或者说您将ContactList创建推送到特定的工厂方法:

EmptyRowProvider.RegisterType(() => ContactListFactory.Create(String.Empty, String.Empty));

最后,您可以使用不同的初始化注册多个不同的类型,但实现相同的用法:

EmptyRowProvider.RegisterType(() => new ContactList(String.Empty, String.Empty, true));
EmptyRowProvider.RegisterType(() => new Person("John", "Doe"));
EmptyRowProvider.RegisterType(() => UserProvider.SetupAnonymousUser("myusername", "mypassword", LoginType.Anonymous));

ContactList emptyContactList = EmptyRowProvider.GetEmptyRow<ContactList>();
Person emptyPerson = EmptyRowProvider.GetEmptyRow<Person>();
User emptyUser = EmptyRowProvider.GetEmptyRow<User>();
于 2012-10-08T02:31:04.650 回答