将CollectionBase子类强制转换为泛型List,而无需显式指定类型

本文关键字:类型 List 子类 CollectionBase 转换 泛型 | 更新日期: 2023-09-27 18:11:51

我有CollectionBase的子类如下:

public abstract class BaseList : CollectionBase
{
    public abstract Type ListType { get; }
}
public class MyClassList : BaseList
{
    public override Type ListType
    {
        get { return typeof(MyClass); }
    }
}

所以我知道编译时的类型。我想添加一个方法ToGenericList()我的BaseList类,将任何BaseList转换为类型的通用ListListType .

这行不通:

public List<T> ToGeneric<T>()
{
    return List.Cast<T>().ToList();
}

,因为"类型参数不能从用法中推断出来。"显然,我可以只需这样做:

someList.Cast<MyClass>().ToList();

或:

someList.ToGeneric<MyClass>();

但是当我在处理具有的对象时,这会使变得非常麻烦列表的列表的列表,我想在它们上面使用一堆LINQ方法,类名有30多个字符长。

是否存在不需要调用者指定类型或选角?

将CollectionBase子类强制转换为泛型List,而无需显式指定类型

没有办法让编译器根据返回类型进行推断。一种选择是为每个集合类型添加一个方法以返回泛型集合:

public class MyClassList : BaseList
{
    public override Type ListType
    {
        get { return typeof(MyClass); }
    }
    public List<MyClass> ToGeneric()
    {
        return this.Cast<MyClass>.ToList();
    }
}

注意,没有办法把它放在基类上,因为唯一改变的是返回类型(你不能通过只改变返回类型来重载一个方法)。

如果你不能或不想改变基本类型,你可以使它们成为扩展方法,但是你仍然必须为每个类型都有一个方法。

如果您的列表有特定的命名约定,您可以尝试大爆炸方法。

首先,声明第二个基类,引入中间层次结构级别:

public abstract class BaseList<T> : BaseList, IList<T>
{
    public override Type ListType { get { return typeof(T); } }
    // Delegate IList<T> implementation to the base class
    public new IEnumerator<T> GetEnumerator()
    {
        return base.Cast<T>().GetEnumerator();
    }
    public void Add(T item)
    {
        base.Add(item);
    }
    public bool Contains(T item)
    {
        return base.Contains(item);
    }
    public void CopyTo(T[] array, int arrayIndex)
    {
        base.CopyTo(array, arrayIndex);
    }
    public bool Remove(T item)
    {
        return base.Remove(item);
    }
    public int IndexOf(T item)
    {
        return base.IndexOf(item);
    }
    public void Insert(int index, T item)
    {
        base.Insert(index, item);
    }
    public new T this[int index]
    {
        get { return (T)base[index]; }
        set { base[index] = value; }
    }
}

然后,嗯…对代码执行正则表达式替换。你可以使用VS 替换文件工具。

:

'bclass's+('w+)List's*:'s*BaseList'b

替换为:

class $1List : BaseList<$1>

这是否可行取决于你的代码库,但这可能是一个开始。

完成后,您可以摆脱现在多余的ListType覆盖。