C#-将未知类型的函数传递给另一个函数并调用它

C#-将未知类型的函数传递给另一个函数并调用它,c#,generic-programming,C#,Generic Programming,在我的程序中,我假设得到一个函数作为参数,并从另一个函数中调用它。能做到吗谢谢你当然,你可以带上一个,然后使用or。除非提供更多信息,否则这将回答您的问题 因此: 例如: Action logEntrance = () => Debug.WriteLine("Entered"); UpdateUserAccount(logEntrance); public void UpdateUserAccount( IUserAccount account,

在我的程序中,我假设得到一个函数作为参数,并从另一个函数中调用它。能做到吗
谢谢你

当然,你可以带上一个,然后使用or。除非提供更多信息,否则这将回答您的问题

因此:

例如:

Action logEntrance = () => Debug.WriteLine("Entered");
UpdateUserAccount(logEntrance);

public void UpdateUserAccount(
           IUserAccount account, 
           Action logEntrance)
{
   if (logEntrance != null)
   {
      logEntrance();
   }
}
  • 使用
    Func
    可以在保留类型安全性的同时使用任意函数

    这可以通过内置Func泛型类完成:

    给定具有以下签名的方法(在本例中,它接受int并返回bool):

    可以将任意函数指定给Func实例:

    var f = new Func<int, int, double>((x,y) => { return x/y; });
    
    有关更多信息,请参阅

  • 当您确实不知道参数,但愿意在运行时调查这些参数时,可以使用反射

    读一下这个。您将传递
    MemberInfo
    的实例。您可以查询其参数以动态发现其编号和类型

  • 使用
    dynamic
    可获得完全自由。没有类型安全性

    在C#4.0中,现在有了
    dynamic
    关键字

    public void foo(dynamic f) {
      f.Hello();
    }
    
    public class Foo {
      public void Hello() { Console.WriteLine("Hello World");}
    }
    
    [Test]
    public void TestDynamic() {
      dynamic d = new Foo();
      foo(d);
    }
    
    更多信息请参见


或者您可以使用lambda表达式。仍然委托,但更快地编写代码

private static void Main(string[] args)
{
    NoReturnValue((i) =>
        {
            // work here...
            Console.WriteLine(i);
        });
    var value = ReturnSometing((i) =>
        {
            // work here...
            return i > 0;
        });
}

private static void NoReturnValue(Action<int> foo)
{
    // work here to determind input to foo
    foo(0);
}

private static T ReturnSometing<T>(Func<int, T> foo)
{
    // work here to determind input to foo
    return foo(0);
}
private static void Main(字符串[]args)
{
NoReturnValue((i)=>
{
//在这里工作。。。
控制台写入线(i);
});
var值=返回值((i)=>
{
//在这里工作。。。
返回i>0;
});
}
私有静态void NoReturnValue(操作foo)
{
//在这里工作以确定foo的输入
foo(0);
}
私有静态T返回函数(Func-foo)
{
//在这里工作以确定foo的输入
返回foo(0);
}

参数,返回类型?如果不知道函数的参数,则很难在运行时传递任何有意义的参数并利用返回值。您可以像这样使用
DynamicInvoke
,但他的示例再次假定委托签名与普通
操作的签名匹配。否则,代码将在运行时失败(这是一件坏事)。您确定不能使用
Func
Action
泛型委托来表示您的方法吗?@Jason Reflection可以处理具有任意数量参数的任何类型的函数。但这可能不是提问者的意思——检查他提问时使用的标签。此外,如果类型未知,为什么你会在回答中假设这意味着0个参数?请删除你的否决票——考虑到你缺乏询问者正在搜索的信息,这是完全没有根据的。我知道它是未知类型。因此,像
Func
这样的强类型解决方案不能、不能、不能工作。当我否决你时,那是你回答的唯一内容<代码>动态
没有帮助,因为至少根据您的源代码示例,您接收的不是委托,而是一个调用该对象上已知名称的方法的对象。这不是问题的目的。我认为使用DynamicVoke调用没有参数的代理是一种过分的做法,为什么需要延迟绑定调用?这是一种性能成本。下面是Invoke与DynamicInvoke的比较。调用x700快一倍,@sllev:Delegate上没有
Invoke
,所以这里没有这个选项<代码>调用仅适用于强类型委托类型。请删除你的否决票。d.DynamicInvoke()我相信这是对一位代表的DynamicInvoke电话?真的,这对我们来说还不清楚me@sllev:您链接到的那篇文章比较了代理上的
DynamicInvoke
Invoke
的性能。问题是
DynamicInvoke
速度较慢,因为它必须进行参数检查。更大的问题是,
Invoke
只存在于强类型委托中,这就是为什么
Invoke
更快的原因:编译器已经在编译时处理了运行时
DynamicInvoke
必须进行的所有参数检查。这就是为什么
Invoke
只能存在于强类型委托中的原因:它将委托类型中的信息合并到
Invoke
的签名中。我理解其中的区别,但不理解为什么使用它。您的示例中,Invoke在这种情况下基本上不起作用?
var f = new Func<int, int, double>((x,y) => { return x/y; });
Assert.AreEqual(2.0, f(6,3));  // ;-) I wonder if that works
public void foo(dynamic f) {
  f.Hello();
}

public class Foo {
  public void Hello() { Console.WriteLine("Hello World");}
}

[Test]
public void TestDynamic() {
  dynamic d = new Foo();
  foo(d);
}
private static void Main(string[] args)
{
    NoReturnValue((i) =>
        {
            // work here...
            Console.WriteLine(i);
        });
    var value = ReturnSometing((i) =>
        {
            // work here...
            return i > 0;
        });
}

private static void NoReturnValue(Action<int> foo)
{
    // work here to determind input to foo
    foo(0);
}

private static T ReturnSometing<T>(Func<int, T> foo)
{
    // work here to determind input to foo
    return foo(0);
}