标签: func

C#Action和Func参数重载

我需要一个采用Action(或Func)的方法,但Action有一个混合数量的参数.实现这些重载的最直接,最紧凑的方法是什么:

public void Execute<T>(Action<T> action, T param) {
    // TODO: Implement something like:
    // Execute(action, param, null);
}

public void Execute<T1,T2>(Action<T1,T2> action, T1 param1, T2 param2) {
    // TODO: Implement something like:
    // Execute(action, param1, param2, null);
}

public void Execute<T1,T2,T3>(Action<T1,T2,T3> action, T1 param1, T2 param2, T3 param3) {
    DoStuff();
    action(param1, param2, param3)
    DoMoreStuff();
}

// OR any other type of higher order function-solution
public void Execute(Action action, params object[] parameters) { ... } // ???
Run Code Online (Sandbox Code Playgroud)

除了执行操作及其参数之外,方法的内容完全相同.

如果可能,请不要使用任何特定于C#4.0的功能来解决此问题.

c# parameters action overloading func

7
推荐指数
2
解决办法
1万
查看次数

我可以定义一个方法来接受一个Func <T>或一个表达式<Func <T >>吗?

如果我尝试写一个方法的两个重载,一个接受Expression<Func<T>>参数而另一个接受a Func<T>,我将在尝试使用lambda表达式调用该方法时遇到编译器错误,因为这两个签名会产生歧义.以下是有问题的,例如:

Method(() => "Hello"); // Is that a Func<string>,
                       // or is it an Expression<Func<string>>?
Run Code Online (Sandbox Code Playgroud)

我明白了.但是我不喜欢只接受一个的方法Expression<Func<string>>,因为这会强制调用代码来使用lambda表达式.如果我也希望能够接受方法组怎么办?

我提出这个问题的基础是,我正在编写一些代码,我希望能够编写这样的代码:

Method(() => "Hello");
Run Code Online (Sandbox Code Playgroud)

...并获得如下输出:

Executed '() => "Hello"' and got "Hello" back.

同时,我也希望能够做到这一点:

Method(ReturnHello);
Run Code Online (Sandbox Code Playgroud)

...并获得如下输出:

Executed 'ReturnHello' and got "Hello" back.

有没有办法做我正在尝试做的事情,而不只是使用两个不同的方法名称(例如,ExpressionMethodFuncMethod)?我意识到这不会是一件大事; 我只是好奇,如果有另一种方式.

.net c# expression overloading func

7
推荐指数
1
解决办法
246
查看次数

C#方式用void返回写Func

我有以下两个功能,几乎相同,唯一的区别是一个使用func,另一个action.如果可能的话,我想将它们组合成一个函数.

    private static void TryCatch(Action action)
    {
        try
        {
            action();
        }
        catch (Exception x)
        {
            Emailer.LogError(x);
            throw;
        }
    }

    private static TResult TryCatch<TResult>(Func<TResult> func)
    {
        try
        {
            return func();
        }
        catch (Exception x)
        {
            Emailer.LogError(x);
            throw;
        }
    }
Run Code Online (Sandbox Code Playgroud)

refactoring delegates action func c#-4.0

7
推荐指数
1
解决办法
6692
查看次数

在一个参数中组合Action和Func

我有很多方法需要一些具有相同模式的日志记录.有些方法需要返回一些值,有些则不需要.我已经创建了一个带有Action参数的方法,以避免对所有逻辑进行复制.它看起来像这样:

private void Execute(Action action)
{
   Logger.Start();
   try
   {
      action();
   }
   catch(Exception exception)
   {
      Logger.WriteException();
      throw;
   }
   finally
   {
       Logger.Finish();
   }
}
Run Code Online (Sandbox Code Playgroud)

现在我有一些类似的电话

public void DoSomething(string parameter)
{
    Execute(() => GetProvider(parameter).DoSomething());
}
Run Code Online (Sandbox Code Playgroud)

但我需要一些返回值的函数.最好的方法是什么?我现在找到了两个:

1)使用Func创建Execute方法的副本

private T Execute<T>(Func<T> action)
{
   Logger.Start();
   try
   {
      return action();
   }
   catch(Exception exception)
   {
      Logger.WriteException();
      throw;
   }
   finally
   {
       Logger.Finish();
   }
}
Run Code Online (Sandbox Code Playgroud)

此方法有效,但也有一些复制粘贴.

2)将参数欺骗为动作:

public Result DoSomething(string parameter)
{
    Result result = null;
    Execute(() => result = GetProvider(parameter).DoSomething());
    return result;
}
Run Code Online (Sandbox Code Playgroud)

这不需要复制粘贴,但看起来不太好.

有没有办法以某种方式加入Action和Func以避免任何这些方法,或者可能有另一种方法来实现相同的结果?

.net c# delegates action func

7
推荐指数
1
解决办法
968
查看次数

Func <>获取参数信息

如何Func<>在C#中获取Lambda 的传递参数的值

IEnumerable<AccountSummary> _data = await accountRepo.GetAsync();
string _query = "1011";
Accounts = _data.Filter(p => p.AccountNumber == _query);
Run Code Online (Sandbox Code Playgroud)

这是我的扩展方法

public static ObservableCollection<T> Filter<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
{
        string _target = predicate.Target.ToString();
        // i want to get the value of query here.. , i expect "1011"

        throw new NotImplementedException();
}
Run Code Online (Sandbox Code Playgroud)

我想在分配给_target的Filter扩展方法中获取查询的值

c# lambda func

7
推荐指数
1
解决办法
6506
查看次数

如何在Linq to Entity Framework的表达式中使用Func?

我正在尝试将linq写入实体扩展方法,该方法使用Func选择属性Id并将其与ID列表进行比较.

public class A
{
    public int AId { get; set; }
}

public class B
{
    public int BId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

扩展方法

public static IQueryable<T> WithId<T>(this IQueryable<T> entities,
    Func<T, int> selector, IList<int> ids)
    {
        Expression<Func<T, bool>> expression = x => ids.Contains(selector(x));
        return entities.Where(expression); // error here (when evaluated)
    }
Run Code Online (Sandbox Code Playgroud)

呼叫方法

var ids = new List<int> { 1, 2, 3 };
DbContext.EntityAs.WithId(e => e.AId, ids);
DbContext.EntityBs.WithId(e => e.BId, ids);
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是它试图调用Entity Framework中不允许的功能.

如何使用属性选择器(Func)来评估查询?

c# linq expression entity-framework func

7
推荐指数
1
解决办法
1万
查看次数

为什么编译器将Func <dynamic,int>的返回类型视为强类型?

为什么以下编译?看起来好像编译器有足够的信息知道尝试的赋值是无效的,因为Func <>的返回类型不是动态的.

Func<dynamic, int> parseLength = whatever => whatever.Length;
dynamic dynamicString = "String with a length";
DateTime wrongType = parseLength(dynamicString);
Run Code Online (Sandbox Code Playgroud)

c# dynamic func

7
推荐指数
1
解决办法
339
查看次数

如何强制将throw作为语句而不是表达式(在lambda表达式中)?

从C#7.0开始,throw关键字既可以用作表达式,也可以用作语句,这很好.但是,请考虑这些过载

public static void M(Action doIt) { /*use doIt*/ }
public static void M(Func<int> doIt) { /*use doIt*/ }
Run Code Online (Sandbox Code Playgroud)

在调用时这样

M(() => throw new Exception());
Run Code Online (Sandbox Code Playgroud)

或者甚至喜欢这样(带有语句lambda)

M(() => { throw new Exception(); });
Run Code Online (Sandbox Code Playgroud)

编译器选择M(Func <>)重载,指示throw在这里被视为表达式.如何优雅和明确地强制编译器选择M(Action)重载?

一种方法是这样做

M(() => { throw new Exception(); return; });
Run Code Online (Sandbox Code Playgroud)

但返回语句的原因似乎并不明显,并且存在被下一个开发人员更改的风险,特别是因为Resharper警告无法访问的代码.

(当然我可以更改方法命名以避免重载,但这不是问题.:-)

c# lambda expression action func

7
推荐指数
2
解决办法
293
查看次数

使用反射创建的Pass方法作为Func参数

我有一个方法(fyi,我正在使用c#),接受一个类型为"Func"的参数,让我们说它是这样定义的:

MethodAcceptingFuncParam(Func<bool> thefunction);
Run Code Online (Sandbox Code Playgroud)

我已经定义了要传递的函数:

public bool DoStuff()
{
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我可以很容易地称之为:

MethodAcceptingFuncParam(() =>  { return DoStuff(); });
Run Code Online (Sandbox Code Playgroud)

这应该是应有的,到目前为止一切顺利.

现在,我想通过反射创建这个方法,而不是传入DoStuff()方法,并将其传递给:

Type containingType = Type.GetType("Namespace.ClassContainingDoStuff");
MethodInfo mi = containingType.GetMethod("DoStuff");
Run Code Online (Sandbox Code Playgroud)

=>这个工作,我可以正确获取methodinfo.

但这就是我被困的地方:我现在想做点什么

MethodAcceptingFuncParam(() => { return mi.??? });
Run Code Online (Sandbox Code Playgroud)

换句话说,我想通过反射传递方法作为MethodAcceptingFuncParam方法的Func参数的值.关于如何实现这一点的任何线索?

c# reflection methods func

6
推荐指数
1
解决办法
1917
查看次数

Func <T,TResult>委托现实世界使用

我最近一直在玩代理Func<T, TResult>并创建返回Func<T, TResult>包含lambda的不同实例的方法,但我一直在努力想出的是为什么人们想要返回(甚至创建这样的实例)的任何好的现实世界观点.

MSDN上有一个例子,它们执行以下操作......

Func<string, string> convertMethod = UppercaseString;
private static string UppercaseString(string inputString)
{
    return inputString.ToUpper();
}
Run Code Online (Sandbox Code Playgroud)

虽然它看起来很漂亮并且是一个有趣的概念,但我没有看到这些代码提供的优势.

那么有人可以提供他们必须使用的任何现实世界的例子,Func<T, TResult>并且一般为什么人们可能想要使用这个代表?

c# lambda anonymous-function func

6
推荐指数
1
解决办法
4282
查看次数