C# 使用Func<;T、 布尔>;[]作为参数列表,并检查每个函数的结果

C# 使用Func<;T、 布尔>;[]作为参数列表,并检查每个函数的结果,c#,parameter-passing,func,type-parameter,C#,Parameter Passing,Func,Type Parameter,更新: 我试图写一个方法来做一些工作,在它真正做这些工作之前,它需要经过一些验证。这些验证取决于它将要做的工作 经过一些思考,我仍然希望使用相同的模式,但有一些细微的变化。 现在,我想让以下代码正常工作: SomeClass: public SomeResponse DoSomething<T>(params Func<T, bool>[] validations) { if(validations.All(v=&

更新: 我试图写一个方法来做一些工作,在它真正做这些工作之前,它需要经过一些验证。这些验证取决于它将要做的工作

经过一些思考,我仍然希望使用相同的模式,但有一些细微的变化。 现在,我想让以下代码正常工作:

SomeClass:

        public SomeResponse DoSomething<T>(params Func<T, bool>[] validations)
        {
            if(validations.All(v=>v(T))
            {
                some logic..
            }
            return SomeResponse;
        }
基本上,类型参数在这里无效,我找不到一种方法将实际的
SomeRequest
对象传递给Func

我应该如何编写代码来循环通过函数列表返回的所有结果,并确保它们返回true,同时保持类型参数的灵活性

回答:

SomeClass:

        public SomeResponse DoSomething<T>(params Func<T, bool>[] validations)
        {
            if(validations.All(v=>v(T))
            {
                some logic..
            }
            return SomeResponse;
        }
找到了这样做的方法,希望这能有所帮助:

只需将方法定义修改为:

某类:

    public SomeResponse DoSomething<T>(T request, params Func<T, bool>[] validations)
    {
        if(validations.All(v=>v(request))
        {
            some logic..
        }
        return SomeResponse;
    }
public SomeResponse DoSomething(T请求,参数Func[]验证)
{
if(validations.All(v=>v(请求))
{
有些逻辑。。
}
回应;
}
然后像这样使用它:

var someResponse = SomeClass.DoSomething<SomeRequest>(someRequest, ValidateName,ValidatePhone);
var someResponse=SomeClass.DoSomething(someRequest、ValidateName、ValidatePhone);

如果有其他解决方案,请告诉我。

假设我正确理解了这些类型,我认为这样的解决方案应该可行:

if (Validations.All(v => v(resource)))
你快到了

首先请注意,
Validations
是一个
Func
数组-也就是说,数组中的每个项都是一个函数,它将
请求
作为参数,并返回一个
bool

因此,为了从
Func
中获取
bool
,您需要将其应用于
请求
对象。在C#中,将
Func
应用于参数就像调用一个方法。因此您的LINQ表达式如下所示:

validations.All(f => f(request))
// I'm just guessing what the code to make a Request object will look like
Request request = resource.GetRequest();

if (!validations.All(f => f(request)))
{
    throw new Exception("Not all of the validations checked out");
}
这将返回
true
当且仅当
验证中的所有函数返回
true
(当应用于
请求时)

因此,完整的
if
块将如下所示:

validations.All(f => f(request))
// I'm just guessing what the code to make a Request object will look like
Request request = resource.GetRequest();

if (!validations.All(f => f(request)))
{
    throw new Exception("Not all of the validations checked out");
}

您没有提供足够的上下文,我无法告诉您从何处获取
请求
对象,但我相信您可以找到它。

您不需要在此处使用
参数
,一个简单的数组就可以了。您可以通过数组传递任意数量的
Func
对象

public void DoSomething(Resource resource, Func<Request, bool>[] Validations)

您好,谢谢您的回复。我对我的问题进行了一些编辑,以使其更具体。问题是,在调用方法时会传递请求对象,就像第一个函数传递了NameRequest一样。它们都是请求的子类型,但我仍然不清楚在if(!validations.All(f=>f(request))中可以使用什么对象。请您详细解释一下好吗?我明白了问题所在-您希望将
Func
Func
传递给
Func
类型的参数。不幸的是,无法这样做,因为
Func
在其第一个参数中是逆变的。
Func
不是
Func
的子类型。(事实恰恰相反)这对我来说意味着你需要重新思考你的设计你到底想实现什么?给定一个特定类型的
请求
,我们是否要求列表中的所有验证器都通过?但是当我尝试使用
NameRequest
但列表中包含一个
PhoneRequest
s的验证器时,会发生什么情况?对于我来说,更合理的是,你真正想要使用的验证器是正确的ator表示您拥有的具体类型的
请求
。为此,您需要在
请求
上使用虚拟方法(
请求.IsValid()
),或者如果您想从需要使用的请求中分离验证代码。非常感谢!您确实照亮了我的路径--访问者模式!我怎么会忘记它!我需要休息一下我想:pYou不能通过第一个类型参数将
Func
Func
转换为
Func
逆变。