如何使用泛型</t>将我的类转换为动态类型<t>

时间:2012-10-08 01:58:26

标签: c# generics

我的功能如下。

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()....

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

2 个答案:

答案 0 :(得分: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()约束,以便您可以使用默认构造函数。

答案 1 :(得分: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>();