C#泛型 - 从消费泛型方法确定泛型类型 [英] C# Generics - Determine generic type from consuming generic method

查看:145
本文介绍了C#泛型 - 从消费泛型方法确定泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

长的故事:我正在一个系统,将有任务处理程序上。任务会从系统的不同部分发送到处理程序,在那里他们最终会返回一个值。

Long story: I'm working on a system that will have Tasks and Handlers. Tasks will be sent from disparate parts of the system to the Handlers, where they will eventually return a value.

我们已经得到了就地一个系统,是弱类型,并已经变成东西粗糙的一塌糊涂的(问题的事实,该任务启动器通常是由第三方组件是未来显著放大基本上插件)。

We've got a system in-place that is loosely-typed and has turned into something of a gnarled mess (the problem is significantly amplified by the fact that the task-initiators are often coming from third-party components that are essentially plug-ins).

我一直在想办法来实现相同的强类型的方式 - 而可能只是以这obsurdity点 - 但我接近我想要的喜欢。现在的问题是一些语法

I've been thinking of ways to implement the same in a strongly-typed fashion--and might just be taking this to the point of obsurdity--but am close to what I'd like. The problem is some syntax.

下面就是我得到了(通用名扩大为清楚起见):

Here's what I've got (generic names expanded for clarity):

interface ITask<ReturnType> { }

interface ITaskHandler<TaskType, TaskReturnType> where TaskType : ITask<TaskReturnType>
{
    TaskReturnType PerformTask(TaskType task);
}

正如你所看到的, ITask 是通用的,并且该声明的泛型参数为 ITask 是返回式为 ITaskHandler&LT; ITask&GT; 。这意味着每个 TaskHandler 终止合约约束,返回由指定类型的 ITask

As you can see, ITask is generic, and the declared generic parameter for ITask is the return-type for ITaskHandler<ITask>. This means that each TaskHandler is contractually bound to return the type specified by its ITask.

大缺点是宣布TaskHandlers导致一些相当丑陋的签名......

The big downside that declaring TaskHandlers leads to some fairly ugly Signatures...

class SpecificTask : ITask<Dictionary<Type,Delegate>>
{
}

class SpecificHandler : ITaskHandler<SpecificTask, Dictionary<Type, Delegate>>
{
    public Dictionary<Type, Delegate> PerformTask(SpecificTask task)
    {
        return new Dictionary<Type, Delegate>();
    }
}

我的问题是:由于 SpecificTask 已经提供了它的返回类型为泛型参数,可以 SpecificHandler 的签名缩短到更多的东西,如:

My question is: since SpecificTask has already provided it's ReturnType as a generic parameter, can SpecificHandler's signature be shortened to something more like:

interface ITaskHandler<TaskType> where TaskType : ITask
{
    // pulling TaskReturnType out of thin air...
    TaskReturnType PerformTask(TaskType task);
}

class SpecificHandler : ITaskHandler<SpecificTask>
{
    public Dictionary<Type, Delegate> PerformTask(SpecificTask task)
    {
        return new Dictionary<Type, Delegate>();
    }
}

...如果是的话,我将如何声明的返回类型 PerformTask 当类型包含在 SpecificTask

推荐答案

不幸的是,你不能做你想做的事,并保留静态类型检查的内容。所有的泛型类型的参数必须按顺序delared的编译器可以静态地知道去哪里。

Unfortunately you can't do what you want to do and retain static type checking. All of the generic type parameters must be delared in order for the compiler to be able to statically know what goes where.

您可以与反思做到这一点,但是这将彻底破坏首先仿制药的目的。

You could do this with reflection but that would completely undermine the purpose of generics in the first place.

这篇关于C#泛型 - 从消费泛型方法确定泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆