2017-02-10 36 views
0

假设我想实现四个类型 参数的泛型类:可选类型参数

class ExampleClass<TA, TB, TC, TD> 
{ } 

类将有许多“使用情况”,因此它可能发生TA和TB是无意义而只有TC和TD需要或相反。有没有一种优雅的方式来使某些类型参数可选?

+1

我想也许你在错误的轨道上。你实际需要完成什么?也许看实际问题可以给出一些关于如何解决问题的策略。 –

+0

该类正在实现发布订阅功能。我想要做的是用请求响应模式来扩展这个类。我想把所有东西放在一个基类中。 – Ozkan

+1

在这种情况下,我会尝试做构图,而不是继承。你有两种行为中的一种,或者两种都有。所以我会说你需要2个基类,每个行为一个,然后用Facade发布这两个基类。如果您需要,我可以扩展我的答案。 –

回答

0

不,与C++模板不同,没有“优雅”的方式;请参阅System.Tuple蛮力方法。请注意,客户端代码通常并不那么糟糕; ExampleClass.Create(...)而不是new ExampleClass<T1, T2, T3>(...)

1

像往常一样,这取决于。我可能会尝试封装用例中的一些静态工厂方法,如下所示:

public class Example<TA, TB, TC, TD> 
{ 
    public TA PropA { get; set; } 
    public TB PropB { get; set; } 
    public TC PropC { get; set; } 
    public TD PropD { get; set; } 

    public static Example<T1, T2, Object, Object> Case1Factory<T1, T2>(T1 a, T2 b) 
    { 
    return new Example<T1, T2, Object, Object>() 
    { 
     PropA = a, 
     PropB = b 
    }; 
    } 

    public static Example<object, object, T3, T4> Case2Factory<T3, T4>(T3 c, T4 d) 
    { 
    return new Example<Object, Object, T3, T4>() 
    { 
     PropC = c, 
     PropD = d 
    }; 
    } 
} 

如果您需要支持超过3个或4个标准的情况下,我会改变做法。

+0

可以将它与类型参数约束(基类)结合起来提供默认行为,而不是使用'Object'作为'可选'类型参数。 –

-1

类型参数只是定义类成员的类型。如果在任何成员中使用类型参数,那些成员需要类型参数,因此它不能是可选的,但必须至少是Object类型。然后你可以决定不使用那些成员,但是班级仍然需要这种类型。

此场景的最优雅的方式是,定义基本类型为你的“可选”类型的参数,因为这样一来,你可以忽略使用非专业化的类型作为类型参数的成员,因为作为时基类型提供任何功能类型参数。

一个例子:

public class MyClass<A, B> where A : BaseA, B : BaseB { 

    public A doSmth(B input) 
    { 
     return input.someMethod(); 
    } 
} 

对于BaseA和BaseB的实现,没有什么特别应该,只要你想他们是可选在这里发生,为此和他们都可以使用。