简体   繁体   English

C#泛型-通过使用泛型方法确定泛型类型

[英]C# Generics - Determine generic type from consuming generic method

Long story: I'm working on a system that will have Tasks and Handlers . 长话短说:我正在开发一个具有TasksHandlers Tasks will be sent from disparate parts of the system to the Handlers, where they will eventually return a value. 任务将从系统的不同部分发送到Handler,最终它们将返回一个值。

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). 我们已经有了一个松散类型的系统,并且变成了一个混乱的混乱局面(由于任务启动器通常来自本质上是插件的第三方组件,因此该问题被大大放大了。 ins)。

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 . 我一直在思考的方式来实现一个强类型的方式是相同的-并且可能只是考虑这obsurdity点-但我接近什么我。 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);
}

As you can see, ITask is generic, and the declared generic parameter for ITask is the return-type for ITaskHandler<ITask> . 正如你所看到的, ITask是通用的,已宣布的泛型参数ITask是返回类型ITaskHandler<ITask> This means that each TaskHandler is contractually bound to return the type specified by its ITask . 这意味着每个TaskHandler都按合同绑定以返回其ITask指定的类型。

The big downside that declaring TaskHandlers leads to some fairly ugly Signatures... 声明TaskHandlers的一大弊端是导致某些相当丑陋的签名...

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>();
    }
}

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: 我的问题是:既然SpecificTask已经提供了它的返回类型为泛型参数,可以SpecificHandler的签名被缩短到更多的东西,如:

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>();
    }
}

...and if so, how would I declare the return type of PerformTask when the type is contained within SpecificTask ? ...如果是的话,当SpecificTask包含该类型时,我该如何声明PerformTask的返回类型?

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. 必须将所有通用类型参数都声明为delar,以便编译器能够静态地知道行进路线。

You could do this with reflection but that would completely undermine the purpose of generics in the first place. 您可以通过反思来做到这一点,但首先会完全破坏泛型的目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM