C# 表达式<;Func<;T、 布尔>>;-如何处理不明确的方法签名?

C# 表达式<;Func<;T、 布尔>>;-如何处理不明确的方法签名?,c#,linq,abstract-class,predicate,linq-expressions,C#,Linq,Abstract Class,Predicate,Linq Expressions,我有一个界面合同,如下所示: ICollection<FooBar> FindByPredicate(Expression<Func<FooBar,bool>> predicate); ICollection<Foo> FindByPredicate(Expression<Func<Foo,bool>> predicate); ICollection<Bar> FindByPredicate(Expression

我有一个界面合同,如下所示:

ICollection<FooBar> FindByPredicate(Expression<Func<FooBar,bool>> predicate);
ICollection<Foo> FindByPredicate(Expression<Func<Foo,bool>> predicate);
ICollection<Bar> FindByPredicate(Expression<Func<Bar,bool>> predicate);
var foo = myService.FindByPredicate<Foo>(f => f.UserId == 1);
它得到了“模糊调用”错误,这是有意义的,因为属性“UserId”存在于抽象的“FooBar”类型上(因此也存在于Foo和Bar上)

那么,我怎样才能克服这个问题呢

我喜欢我的接口(重载谓词方法)的外观,因为从调用代码的intellisense角度来看,只有一个方法名

为什么我有这样的界面?嗯,有些场景我只想返回“Foo”或“Bar”,其他时候我需要一个混合包,因此我需要返回抽象类型-有意义吗


不管怎样,关于一个显而易见的问题——有没有办法解决这个问题?(除了重命名我的接口方法)?(从而降低了简单性)

您可以在lambda中声明
f
的类型,而不是让它被推断出来。这样,只有一个过载将适用

var foo = myService.FindByPredicate((Foo f) => f.UserId == 1);
var bar = myService.FindByPredicate((Bar f) => f.UserId == 1);
var foobar = myService.FindByPredicate((FooBar f) => f.UserId == 1);

您可以将该方法声明为泛型,然后只需要一个方法:

public interface IFooBarService
{
    ICollection<T> FindByPredicate<T>(Expression<Func<T, bool>> predicate)
        where T : FooBar;
}
公共接口IFooBarService
{
ICollection FindByPredicate(表达式谓词)
式中T:FooBar;
}
然后你可以这样称呼它:

ICollection<FooBar> FindByPredicate(Expression<Func<FooBar,bool>> predicate);
ICollection<Foo> FindByPredicate(Expression<Func<Foo,bool>> predicate);
ICollection<Bar> FindByPredicate(Expression<Func<Bar,bool>> predicate);
var foo = myService.FindByPredicate<Foo>(f => f.UserId == 1);
var foo=myService.FindByPredicate(f=>f.UserId==1);

我有一个想法-有没有一种方法可以创建从表达式派生的类并在接口签名中使用这些类?(从而解决了歧义问题)?Expression/Func是密封类,dang。我在这里不知所措!不错(+1)。谢谢我不想强制转换,但我会选择它,而不是简单的界面。RPM1984:这不是强制转换;它只是声明了
f
的类型,而不是让编译器推断出来。很抱歉,从你这里拿走了答案=),但我更喜欢Timwi的答案,因为它减少了接口契约中的定义量。不过谢谢你的帮助。谢谢,但是我需要根据类型应用特定的操作-因此我不能将其冒泡到通用的T(当然我可以,但是如果T是Foo,我需要)。我需要保持界面的原样。谢谢。@RPM1984:很公平——但我认为这是糟糕的界面设计。您希望应用特定操作是一个实现细节,应该是实现接口的类的私有信息。是的,您需要一个
if
来选择要调用的正确私有方法。我会认为这是正确的解决方案。@ TimWi--接口如何声明?我有:
公共接口IFooBarService
。它给出了错误“无法解析符号T”@RPM1984:它没有给我这个错误。我已经更新了答案以包含整个接口声明。我在这里所做的更改是在其周围添加
公共接口IFooBarService
{
..
}
。@Timwi-谢谢,我错过了FindByPredicate之后的页面(duh!)。我将实现代码,看看我的单元测试是否通过。这无疑是更好的解决方案,因为我有大约10个接口方法,这将使它下降到1。当然,它需要工作我会让你知道。。。