打开通用约束

Bre*_*ias 8 c# generics

给出以下界面:

public interface IQuerySpec<M> { }
Run Code Online (Sandbox Code Playgroud)

我想做一个像这样的扩展方法:

public static OrderedSortation<T> OrderBy<T, TKey>(
    this T query, 
    Expression<Func<T, TKey>> sort) 
where T : IQuerySpec<?> {
    //business as usual
}
Run Code Online (Sandbox Code Playgroud)

我只是想确定类型T是一些变体IQuerySpec<M>.然后我可以调用扩展方法如下:

public class Foo : IQuerySpec<int> {
   public int SizeOfSailBoat {get; set;}
}

IQuerySpec<Foo> foo = new Foo {SizeOfSailBoat = 10}.
var result = foo.OrderBy(f => f.SizeOfSailBoat);
Run Code Online (Sandbox Code Playgroud)

Foo在上面的例子中指定了UDT ,但我不关心使用什么泛型类型参数.

有没有办法做到这一点?

我尝试了以下方法:

public static OrderedSortation<T> OrderBy<T, M, TKey>(
    this T query, 
    Expression<Func<T, TKey>> sort) 
where T : IQuerySpec<M> {
    //business as usual
}
Run Code Online (Sandbox Code Playgroud)

上述工作,但要求明确声明通用参数,以调用"OrderBy".我不希望被要求明确说明通用参数.

我也试过这个:

public interface IQuerySpec {}
public interface IQuerySpec<M> : IQuerySpec {}
Run Code Online (Sandbox Code Playgroud)

有了这些接口,我就可以这样做:

public static OrderedSortation<T> OrderBy<T, TKey>(
    this T query, 
    Expression<Func<T, TKey>> sort) 
where T : IQuerySpec {
    //business as usual
}
Run Code Online (Sandbox Code Playgroud)

这几乎是足够好的,除了我想要隐藏非泛型IQuerySpec,以便它在我的类库之外不可见.如果我能以这种方式限制非通用接口,我会很高兴:

internal interface IQuerySpec {}
Run Code Online (Sandbox Code Playgroud)

不幸的是,编译器不会让我这样做.

我猜我想要的是不可能的,但要求以防万一.

Ala*_*din 0

问题是编译器无法隐式地从 T 推断出 M 的类型,或者从 M 推断出 T 的类型。

所以你需要修复其中一个,这里我将 T 修复为IQuerySpec<M>

扩展方法的签名变为

    public static OrderedSortation<IQuerySpec<M>> OrderBy<M, TKey>(
     this IQuerySpec<M> query,
     Expression<Func<IQuerySpec<M>, TKey>> sort)

    {
        //business as usual
    }
Run Code Online (Sandbox Code Playgroud)

举个例子

    class IntQSpec : IQuerySpec<int>
    {
        //your implementation
    }
Run Code Online (Sandbox Code Playgroud)

这是调用示例

var iQS = new IntQSpec();
//do whatever you want with iQS
var ord = iQS.OrderBy(ii=>ii.ToString());
//here I called OrderBy without the need to explicitly specifying the Generic Arguments
Run Code Online (Sandbox Code Playgroud)

这是在 Visual Studio 2013-2015 上对您的代码进行的测试,没有错误,突出显示我访问了具体类型的 Z 字段IntQSpec 在此输入图像描述

我希望它会有所帮助。