C#模板和特殊构造函数

时间:2009-02-03 22:26:02

标签: c# generics oop templates

我有一些类,它们都能够使用作为特定接口实例的参数构造。因为它们都可以由同一个对象构建(并且在这种情况下,这种构造发生的过程在所有情况下大致相同),我想也许模板化会起作用。基本上,我想做这样的事情:

public static void dostuff<T, U> (List<T> items)
{
    foreach (T item in items)
    {
        func(new U(item).SpecialMember);
    }
}

当然,这不会编译,因为U是模板化的,因此缺少SpecialMember以及T构造函数。

基本上,接口T的任何给定实现都具有某些特征。 UT which has an additional feature that is needed *and* which can be constructed from an any instance of U`的实现。

么?

5 个答案:

答案 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);
    }
}