有没有办法避免在C#中链接泛型类型参数?

时间:2010-08-01 15:08:46

标签: c# generics

我可能会遗漏一些明显的东西;但如果我有以下内容:

public interface IRequest<out T>
    where T : class 
{
    T Request
    {
        get;
    }
}

public interface IResponse<out T>
    where T : class 
{
    T Response
    {
        get;
    }
}

然后是第三个使用这些接口作为泛型类型参数的接口:

public interface IResponder<in TRequest, TRequestValue, out TResponse, TResponseValue>
    where TRequest : IRequest<TRequestValue>
    where TResponse : IResponse<TResponseValue>
    where TRequestValue : class 
    where TResponseValue : class
{
    TResponse Query(TRequest request);
}

有没有办法避免将TRequestValueTResponseValue作为通用参数传递给IResponder(因此避免重复关联的约束)?

基本上我更喜欢使用类似于以下内容的东西来减少IResponder的泛型类型参数的数量(我意识到目前不会编译):

public interface IResponder<in TRequest, out TResponse>
    where TRequest : IRequest
    where TResponse : IResponse
{
    TResponse Query(TRequest request);
}

我能想到这样做的唯一方法是编写两个非通用接口(IRequestIResponse),然后使IRequest<T>IResponse<T>实现这些,但这在某种程度上似乎是错误的。

我完全清楚我可能因为我在这里做事的方式而遇到了这个问题,所以请随意提出我做错了什么!

注意:整个请求,响应,响应者示例实际上不是我正在编写的代码,而是尝试支持我的问题的示例。

2 个答案:

答案 0 :(得分:1)

没有。 IRequest不一定是IRequestValue。 很清楚,但这只是因为抽象语义。编译器无法知道。

如果您对函数参数采用相同的方法,请考虑一下。假设编译器可以推断出tramp参数是否合理?不,你必须手动传递它们,并且无法解决它。

答案 1 :(得分:1)

创建单独的非通用接口的想法实际上是C#中适用于非通用场景的常用方法。 (例如,参见IList&lt; T&gt;和IList)IMO,很有可能在你的情况下,仿制药根本不会增加很多价值。看起来您正在使用它们来约束人们如何使用您的类,而不是试图实际重用并简化您的代码。我的建议是使用非通用的IRequest和IResponse接口,只需让Responder直接使用它们而不需要任何泛型。如果你真的认为查询方法必须具有完全正确的类型而不必进行任何转换,那么你应该全力以赴并接受所有类型约束的详细程度。