表达式> - 如何处理不明确的方法签名?

发布于 2024-09-18 08:17:43 字数 782 浏览 14 评论 0 原文

我有一个如下所示的接口契约:

ICollection<FooBar> FindByPredicate(Expression<Func<FooBar,bool>> predicate);
ICollection<Foo> FindByPredicate(Expression<Func<Foo,bool>> predicate);
ICollection<Bar> FindByPredicate(Expression<Func<Bar,bool>> predicate);

Foo 和 Bar 是从 FooBar 抽象类继承的具体类。

现在,我在尝试调用这些方法时遇到了问题:

var foo = myService.FindByPredicate(f => f.UserId == 1);

它收到“模糊调用”错误,这是有道理的,因为属性“UserId”存在于抽象“FooBar”类型上(因此存在于 Foo 和 Bar 上,如出色地)。

那么,我该如何克服这个问题呢?

我喜欢我的界面(重载谓词方法)的外观,因为从调用代码的智能感知角度来看,只有一个方法名称。

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

无论如何,关于一个显而易见的问题——有没有办法解决这个问题? (除了重命名我的接口方法之外)? (从而损害了简单性)

I have an interface contract that looks like this:

ICollection<FooBar> FindByPredicate(Expression<Func<FooBar,bool>> predicate);
ICollection<Foo> FindByPredicate(Expression<Func<Foo,bool>> predicate);
ICollection<Bar> FindByPredicate(Expression<Func<Bar,bool>> predicate);

Foo and Bar are concrete classes which inherit from the FooBar abstract class.

Now, im running into problems when trying to invoke these methods:

var foo = myService.FindByPredicate(f => f.UserId == 1);

It's getting "Ambigious invocation" errors, which kind of makes sense, because the property "UserId" exists on the abstract "FooBar" type (and thus exists on Foo and Bar as well).

So, how can i overcome this?

I like the look of my interface (overloaded predicate methods) as from an intellisense point of view from the calling code, there is only one method name.

Why do i have my interface like that? Well, some scenarios i wish to return only "Foo" or "Bar", other times i need a mixed bag, hence i need to return the abstract type - make sense?

Anyway, onto the obvious question - is there a way around this? (other than renaming my interface methods)? (and thus compromising the simplicity)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

傲世九天 2024-09-25 08:17:43

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

public interface IFooBarService
{
    ICollection<T> FindByPredicate<T>(Expression<Func<T, bool>> predicate)
        where T : FooBar;
}

然后你可以像这样调用它:

var foo = myService.FindByPredicate<Foo>(f => f.UserId == 1);

You can declare the method to be generic, and then you need only one method:

public interface IFooBarService
{
    ICollection<T> FindByPredicate<T>(Expression<Func<T, bool>> predicate)
        where T : FooBar;
}

and then you can call it like this:

var foo = myService.FindByPredicate<Foo>(f => f.UserId == 1);
握住你手 2024-09-25 08:17:43

您可以在 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);

You can declare the type of f in the lambda rather than let it be inferred. That way, only one overload will be applicable.

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文