Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何通过反射执行带有可选参数的私有静态方法?_C#_Reflection_C# 4.0_.net 4.0_Optional Parameters - Fatal编程技术网

C# 如何通过反射执行带有可选参数的私有静态方法?

C# 如何通过反射执行带有可选参数的私有静态方法?,c#,reflection,c#-4.0,.net-4.0,optional-parameters,C#,Reflection,C# 4.0,.net 4.0,Optional Parameters,我有一个带有可选参数的私有静态方法的类。如何通过反射从另一个类调用它?有一个类似的方法,但它不处理静态方法或可选参数 public class Foo { private static void Bar(string key = "") { // do stuff } } var method = typeof(Foo).GetMethod("Bar", BindingFlags.Static | BindingFlags.NonPublic); 如何调用Foo

我有一个带有可选参数的私有静态方法的类。如何通过反射从另一个类调用它?有一个类似的方法,但它不处理静态方法或可选参数

public class Foo {
    private static void Bar(string key = "") {
       // do stuff
    }
}
var method = typeof(Foo).GetMethod("Bar", BindingFlags.Static | BindingFlags.NonPublic);

如何调用
Foo.Bar(“test”)
Foo.Bar()
(例如,在不传递可选参数的情况下)?

C中的可选参数值通过在调用站点注入这些值来编译。即,即使您的代码是

Foo.Bar()
编译器实际上生成一个调用,如

Foo.Bar("")
在查找方法时,需要将可选参数视为常规参数

public class Foo {
    private static void Bar(string key = "") {
       // do stuff
    }
}
var method = typeof(Foo).GetMethod("Bar", BindingFlags.Static | BindingFlags.NonPublic);
如果您确切知道要使用哪些值调用该方法,则可以执行以下操作:

method.Invoke(obj: null, parameters: new object[] { "Test" });
如果您只有一些参数,并且希望使用默认参数的值,那么您必须检查该方法的对象,以查看这些参数是否可选以及这些值是什么。例如,要打印出这些参数的默认值,可以使用以下代码:

foreach (ParameterInfo pi in method.GetParameters())
{
    if (pi.IsOptional)
    {
        Console.WriteLine(pi.Name + ": " + pi.DefaultValue);
    }
}
使用这个类

  public class Foo
  {
    private static void Bar(string key = "undefined key", string value = "undefined value")
    {
      Console.WriteLine(string.Format("The key is '{0}'", key));
      Console.WriteLine(string.Format("The value is '{0}'", value));
    }
  }
您可以使用以下代码使用默认值调用它

  MethodInfo mi = typeof(Foo).GetMethod("Bar", BindingFlags.NonPublic | BindingFlags.Static);
  ParameterInfo[] pis = mi.GetParameters();

  object[] parameters = new object[pis.Length];

  for (int i = 0; i < pis.Length; i++)
  {
    if (pis[i].IsOptional)
    {
      parameters[i] = pis[i].DefaultValue;
    }
  }

  mi.Invoke(null, parameters);
需要你做什么

parameters[0] = "23"

在调用我为单元测试编写的东西之前:

    /// <summary>
    /// Attempts to execute a function and provide the result value against the provided source object even if it is private and/or static. Just make sure to provide the correct BindingFlags to correctly identify the function.
    /// </summary>
    /// <typeparam name="TReturn">The expected return type of the private method.</typeparam>
    /// <param name="type">The object's Type that contains the private method.</param>
    /// <param name="source">The object that contains the function to invoke. If looking for a static function, you can provide "null".</param>
    /// <param name="methodName">The name of the private method to run.</param>
    /// <param name="flags">Binding flags used to search for the function. Example: (BindingFlags.NonPublic | BindingFlags.Static) finds a private static method.</param>
    /// <param name="output">The invoked function's return value.</param>
    /// <param name="methodArgs">The arguments to pass into the private method.</param>
    /// <returns>Returns true if function was found and invoked. False if function was not found.</returns>
    private static bool TryInvokeMethod<TReturn>(Type type, object source, string methodName, BindingFlags flags, out TReturn output, params object[] methodArgs)
    {
        var method = type.GetMethod(methodName, flags);
        if(method != null)
        {
            output = (TReturn)method.Invoke(source, methodArgs);
            return true;
        }

        // Perform some recursion to walk the inheritance. 
        if(type.BaseType != null)
        {
            return TryInvokeMethod(type.BaseType, source, methodName, flags, out output, methodArgs);
        }

        output = default(TReturn);
        return false;
    }

免责声明:我仅将其用于具有返回值的函数。尝试执行没有返回值的方法将引发异常。

静态方法部分如何?