【问题标题】:c# call method based on contents of a variablec#根据变量内容调用方法
【发布时间】:2012-07-24 02:50:29
【问题描述】:

如何根据变量的内容调用方法

例如。

String S = "Hello World";
String Format = "ToUpper()";

String sFormat = s.Format;

resulting in "HELLO WORLD"

这样我可以在其他时间传递Format = "ToLower()" 或 Format = "Remove(1,4)" 这将从 pos 1 开始删除 4 个字符 - 简而言之,我希望能够调用任何字符串方法。

有人可以发布一个完整的工作解决方案。

【问题讨论】:

  • 你可以通过反射轻松地做到这一点......但它不会是有史以来最快的代码。
  • 真正的问题是;这是解决问题的最佳方法吗?
  • ...以及它实际上如何(或在什么情况下)帮助您?!
  • 嗨,欢迎来到 SO! “发布一个完整的工作解决方案”不是我们在此处一般的习惯,但我们很乐意帮助您并为您提供提示。您是否有遇到任何特殊问题的代码示例或 sn-p?

标签: c#


【解决方案1】:

解决方案的关键是需要您使用反射来定位所需的方法。这是一个涵盖您的情况的简单示例;

private string DoFormat(string data, string format)
{
    MethodInfo mi = typeof (string).GetMethod(format, new Type[0]);
    if (null == mi)
        throw new Exception(String.Format("Could not find method with name '{0}'", format));

    return mi.Invoke(data, null).ToString();
}

您可以使该方法更通用,以接受您要调用的方法的参数,如下所示。请注意调用 .GetMethod 和 .Invoke 以传递所需参数的方式发生了变化。

private static string DoFormat(string data, string format, object[] parameters)
{
    Type[] parameterTypes = (from p in parameters select p.GetType()).ToArray();

    MethodInfo mi = typeof(string).GetMethod(format, parameterTypes);
    if (null == mi)
        throw new Exception(String.Format("Could not find method with name '{0}'", format));

    return mi.Invoke(data, parameters).ToString();
}

【讨论】:

  • 您的解决方案适用于 ToUpper 或 ToLower 但我如何通过 Replace(1,4)
  • 见上面的编辑。您需要调用不同的 GetMethod 和 Invoke 重载来将参数传递给“DoFormat”方法。
【解决方案2】:

您可以通过反射来做到这一点,但是代码变得难以阅读,并且类型安全性消失了。

C# 提供了一种更好的机制来传递可执行代码 - 即委托。

你可以这样做:

void ShowConverted(string str, Func<string,string> conv) {
    Console.WriteLine("{0} -- {1}", str, conv(str));
}

Func<string,string> strAction1 = (s) => s.ToUpper();
Func<string,string> strAction2 = (s) => s.ToLower();
ShowConverted("Hello, world!", stringAction1);
ShowConverted("Hello, world!", stringAction2);

【讨论】:

    【解决方案3】:

    您可以使用反射从字符串类型中拉出 ToLower() 方法。

      string format = "Hello World";
      MethodInfo methodInfo = typeof(string).GetMethod("ToLower");
      string result = methodInfo.Invoke(format,null);
    

    我可能把语法弄乱了一点

    【讨论】:

      【解决方案4】:

      为什么不直接使用这些方法。

      Func<string, string> format = s = > s.ToUpper();
      

      然后你就可以了

      format = s = > s.ToLower();
      

      否则,您将不得不使用 Reflection,这不安全并且可能更慢。

      【讨论】:

      • 如果要使用的方法是在外部指定的(例如,在配置文件中),您仍然需要一些方法将方法名称转换为方法。
      • @RJLohan 如果他必须使用字符串,我仍然会使用枚举来选择正确的方法。
      【解决方案5】:

      你可以在这里使用反射。看看MethodInfo类。

      【讨论】:

        【解决方案6】:

        这样的方法可以工作,但我面前没有编译器来验证。

        像这样使用它:

        var result = someObject.CallParameterlessMethod("ToUpper");
        
        
        
        
        public static class ObjectExtensionMethods
        {
          public static object CallParameterlessMethod(this object obj, string methodName)
          {
            var method = typeof(obj).GetMethod(methodName);
            return method.Invoke(obj,null);
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-07-30
          • 1970-01-01
          • 1970-01-01
          • 2016-02-04
          • 1970-01-01
          • 1970-01-01
          • 2017-01-19
          相关资源
          最近更新 更多