【问题标题】:Store reference to method to be called later with different parameters存储对稍后使用不同参数调用的方法的引用
【发布时间】:2014-12-21 04:36:01
【问题描述】:

我需要能够让一个变量类型存储对不同方法的引用,然后用不同的参数调用它们,并让它们返回一些东西。这些方法将具有不同的参数类型和输出类型。我已经尝试过委托、动作和 Func。

下面的伪代码示例

  public void Open(String directory){
  File.Open(Directory);
  }
  public string ChangeVolume(int volume){
  //Code to change volume 
  //return the new volume
  }
public static void Main{
 MyVaribleType var1 = Open;
 myVaribleType var2 = ChangeVolume;
  var1("C:\Windows");
  Console.WriteLine(var2(100) );
}

我将如何使用单个变量类型完成此操作?

【问题讨论】:

  • 你真的做不到。
  • 您不能为两种不同的类型使用一个“变量类型”。 void 不是 stringString 不是 int。但是,您可以将签名更改为 object Method(object[] params) 以尽可能通用,但我不建议这样做。
  • 告诉我们您要解决的问题。也许有比这更好的解决方法。
  • 这是一个人工智能。当人工智能看到一个词时,它必须进入它的记忆并搜索这个词,然后执行与那个词相关的动作/方法,但是与那个词相关的动作可能会改变(学习人工智能,或者我手动改变它)

标签: c# methods delegates wrapper


【解决方案1】:

您可以保存对反射 API 提供的 MethodInfo 类集合中方法的引用。为了能够调用这些方法,您还需要保留要调用这些方法的对象的引用。您可以使用反射本身来调用这些方法。反射很慢,所以只有在对性能要求不高的情况下才可以使用此方法。

【讨论】:

  • 这非常有效,但我还不知道速度是否会成为问题。谢谢.... 将新的工作代码发布给其他人查看也是一种好习惯
  • 谢谢。这是我关于堆栈溢出的第一个答案,我正在手机上使用它。
【解决方案2】:

你不能完全按照你的意愿去做:这两种方法有不同的签名,正如@Mephy 所说。不过,您可以使用委托来做到这一点:

public delegate FileStream OpenFileHandler(string filePath);
public delegate string ChangeVolumeHandler(FileStream stream, int volume);

class Program
{
    private static FileStream Open(string filePath)
    {
        return File.Open(filePath, FileMode.OpenOrCreate);
    }
    private static string ChangeVolume(FileStream stream, int volume)
    {
        return "Done! Honest!";
    }
    static void Main(string[] args)
    {
        OpenFileHandler ofh = Program.Open;
        ChangeVolumeHandler cvh = Program.ChangeVolume;
        FileStream stream = ofh("path");
        string xyzzy = cvh(stream, 100);
    }
}

我不确定您为什么要这样做,但我认为您已经展示了这是一个相当复杂的要求,很好。

请注意,除了必须使用两个委托之外,您还必须传递每个需要处理和创建的项目(例如 FileStream 对象)。

【讨论】:

    【解决方案3】:

    您可以使用ExpandoObject

    dynamic d = new ExpandoObject();
    d.ChangeVolume = new Func<int, string>(ChangeVolume);
    

    然后这样称呼它:

    var result = d.ChangeVolume(volume);  //ChangeVolume is type-checked at runtime.
    

    或者直接将逻辑写入新的动态属性中:

    d.ChangeVolume = new Func<int, string>(x => (x * x).ToString()); // or whatever
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多