我有一些类,它们都能够使用作为特定接口实例的参数构造。因为它们都可以由同一个对象构建(并且在这种情况下,这种构造发生的过程在所有情况下大致相同),我想也许模板化会起作用。基本上,我想做这样的事情:
public static void dostuff<T, U> (List<T> items)
{
foreach (T item in items)
{
func(new U(item).SpecialMember);
}
}
当然,这不会编译,因为U
是模板化的,因此缺少SpecialMember
以及T
构造函数。
基本上,接口T
的任何给定实现都具有某些特征。 U
是T which has an additional feature that is needed *and* which can be constructed from an any instance of
U`的实现。
么?
答案 0 :(得分:4)
不幸的是,虽然约束会让你某些,但是没有办法指定一个类型有一个带有某个参数的构造函数:你可以要求的唯一构造函数是无参数构造函数。 / p>
就个人而言,我希望看到使用"static interfaces"的概念进行更改(仅适用于类型约束),但目前最好的是类型工厂或反射 - 或者可能是无参数构造函数和界面中的“Init”方法。坦率地说,这些都不是很好的选择。
答案 1 :(得分:2)
您可以将constraints添加到通用参数中,以便您访问SpecialMember,例如:
public class SpecialObjFactory<T,U> where T : ISpecialMethod
where u : new()
{
}
答案 2 :(得分:0)
您需要Factory模式。在T接口中添加一个返回U类型的工厂方法。
答案 3 :(得分:0)
您不能使用泛型来创建这样的对象。您可以像这样限制泛型类型:
public static void dostuff<T, U> (List<T> items) where T : SomeClass where U : SomethingElse
{
}
但这只会让你访问那些类/接口的成员,而不是构造函数。
为了扩展Joel的答案,你应该在T接口(在我的例子中,SomeClass)中添加一个方法,它接受一个T对象并返回一个新的U对象。如下所示:
public class SomeClass
{
CreateInstanceOfSomethingElse() { return new SomethingElse(this); }
}
public static void dostuff<T, U> (List<T> items) where T : SomeClass, U : SomethingElse
{
foreach (T item in items)
{
func(item.CreateInstanceOfSomethingElse().SpecialMember);
}
}
作为另一种完全不同的方法,您可以指定doStuff方法也使用Func<T, U>
,这应该从T对象创建U.
public static void dostuff<T, U> (List<T> items, Func<T, U> createU)
{
foreach (T item in items)
{
func(createU(item).SpecialMember);
}
}
如果您的对象创建比简单的lamba(如
)更复杂,那么这会变得混乱 t => new U(t)
答案 4 :(得分:0)
public static void dostuff<T, U> (List<T> items)
{
foreach (T item in items)
{
U obj = ( U )System.Activator.CreateInstance( typeof( U ), item );
func(obj.SpecialMember);
}
}