键入泛型类型参数使用的泛型约束

时间:2017-01-04 21:02:32

标签: c# generics

我正在尝试定义一个接口IScheduler,它接受​​T1并返回T2,并且还有IJob<T1,T2>的类型参数,以便它知道创造什么工作。我想这样称呼它:

public class SomeJob : IJob<string, int>

// preferred way to use the method
int result = scheduler.Schedule<SomeJob>("some_param");

让编译器推断出T1是一个字符串而T2是一个int。这就是我尝试定义界面

的方法
public interface IScheduler
{
    T2 Schedule<TJob, T1, T2>(T1 args) where TJob: IJob<T1, T2>;
}

不幸的是,编译器抱怨:

Using the generic method 'Schedule<TJob,T1,T2>(T1)' requires 3 type arguments

The type 'SomeJob' must be convertible to 'Job<T1, T2>' in order to use it as parameter 'TJob` in the generic method 'T2 IScheduler.Schedule<TJob,T1,T2>(T1)'

我真正想做的是:

public interface IScheduler
{
    T2 Schedule<TJob>(T1 args) where TJob: IJob<T1, T2>;
}

1 个答案:

答案 0 :(得分:1)

获取您正在寻找的语法是不可能的,但这里有一些可行的方法:

int result = scheduler.Schedule(new SomeJob(), "some_param");

// using this
public interface IScheduler
{
    T2 Schedule<T1, T2>(IJob<T1, T2> job, T1 args);
}

或者:

int result = scheduler.ForJob<SomeJob>.Schedule("some_param");

// using this
public interface IScheduler
{
    IJobScheduler<TJob> ForJob<TJob>();
}
public interface IJobScheduler<out TJob> { }

public static class Extensions 
{
    public static T2 Schedule<T1, T2>(this IJobScheduler<IJob<T1, T2>> job, T1 args)
    {
        ...
    }
}

或者如果你可以摆脱return参数,你可以在TJob方法中访问强类型Schedule

scheduler.ForJob<JobWithNoReturn>().Schedule("some_param");

// using the stuff from #2 and also this
public static class Extensions 
{
    ...

    public static void Schedule<TJob, T1>(this IJobScheduler<TJob> job, T1 args)
        where TJob : IJob<T1>
    {
        ...
    }
}