我有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
类会将任何List
转换为类型的通用ListType
public List<T> ToGeneric<T>()
{
return List.Cast<T>().ToList();
}
。
这不起作用:
someList.Cast<MyClass>().ToList();
因为“无法根据用法推断出类型参数。”显然,我可以 这样做:
someList.ToGeneric<MyClass>();
或者这个:
#include <iostream>
#include <type_traits>
template <typename R, typename S>
class ICanDoIt
{
public:
virtual void doStuff() = 0;
protected:
ICanDoIt<R, S>(R rA, S sA) : r(rA), s(sA) {};
R r;
S s;
};
class DoesIt : public ICanDoIt<int, double>
{
public:
DoesIt(int iA, double dA) : ICanDoIt(iA, dA) {};
virtual void doStuff()
{ std::cout << "r * s = " << r * s << " done." << std::endl; }
};
template <typename T>
class NeedsSomeoneWhoCanDoIt
{
static_assert(std::is_base_of<ICanDoIt<R, S>, T>::value,
"T needs to be able to do it.");
public:
NeedsSomeoneWhoCanDoIt(const T& doesItA) : doesIt(doesItA) {};
void getItDone() { doesIt.doStuff(); };
private:
T doesIt;
};
int main()
{
DoesIt doesIt(5, 2.2);
NeedsSomeoneWhoCanDoIt<DoesIt> needsIt(doesIt);
needsIt.getItDone();
}
但是当我使用具有的对象时,这会使非常麻烦 列表列表的列表,我想在它们上面使用一堆LINQ方法,类名称长度超过30个字符。
是否有任何解决方案不涉及调用者指定类型或 一点都没有?
答案 0 :(得分:2)
没有办法让编译器通过返回类型进行推断。一种选择是为每个集合类型添加一个方法以返回泛型集合:
public class MyClassList : BaseList
{
public override Type ListType
{
get { return typeof(MyClass); }
}
public List<MyClass> ToGeneric()
{
return this.Cast<MyClass>.ToList();
}
}
请注意,没有办法将它放在基类上,因为唯一改变的是返回类型(不能通过仅更改返回类型来重载方法)。
如果您不能/不想更改可以使其成为扩展方法的基本类型,但您仍需要为每种类型设置方法。
答案 1 :(得分:1)
如果您的列表具有特定的命名约定,则可以尝试大爆炸方法。
首先,声明第二个基类,引入中间层次结构级别:
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
覆盖。