编程语言
首页 > 编程语言> > c#-如果具有方法/扩展方法,则调用它

c#-如果具有方法/扩展方法,则调用它

作者:互联网

我正在为字典制作ToDebugString()方法,但是如果该类型可用,我还希望它对任何项目使用ToDebugString()方法.

由于ToDebugString()有时被实现为本机.NET类型(例如字典和列表)的扩展方法,因此我在检查该方法是否存在时遇到了麻烦.我只将扩展方法放在一个称为ExtensionMethods的类中,因此我可能只需要在一个其他类中进行搜索.

兴趣点在这里:

ToDebugString()抱怨类型参数.另外,由于Value是泛型类型,因此它不会自动建议ToDebugString()方法,因此我认为那里也存在问题.

kv.Value.HasMethod("ToDebugString") ? kv.Value.ToDebugString() : kv.Value.ToString()

如果我不使用本机.NET类型,那么我想实现一个通用接口就是解决方案.

这是完整的代码段:

// via: https://stackoverflow.com/a/5114514/796832
public static bool HasMethod(this object objectToCheck, string methodName) {
    var type = objectToCheck.GetType();
    return type.GetMethod(methodName) != null;
} 

// Convert Dictionary to string
// via: https://stackoverflow.com/a/5899291/796832
public static string ToDebugString<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
{
    return "{" + string.Join(", ", dictionary.Select(kv => kv.Key.ToString() + "=" + (kv.Value.HasMethod("ToDebugString") ? kv.Value.ToDebugString() : kv.Value.ToString())).ToArray()) + "}";
}

也是here are a small tests我为试图获得HasMethod()给出正确的.

解决方法:

之所以没有调用您的扩展方法,是因为扩展方法属于定义它们的类型,因此调用如下:

"Hello world".MyExtensionMethod()

在引擎盖下转换为:

ExtensionMethods.MyExtensionMethod("Hello world"));// "Hello world".MyExtensionMethod()

This topic包含一些代码示例,该代码示例如何获取特定类的所有扩展方法,我对代码进行了扩展,以下是按名称运行扩展方法的代码:

    // the utility code

    internal static class ExtensionMethodsHelper
    {
        private static readonly ConcurrentDictionary<Type, IDictionary<string, MethodInfo>> methodsMap = new ConcurrentDictionary<Type, IDictionary<string, MethodInfo>>();

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static MethodInfo GetExtensionMethodOrNull(Type type, string methodName)
        {
            var methodsForType = methodsMap.GetOrAdd(type, GetExtensionMethodsForType);
            return methodsForType.ContainsKey(methodName)
                ? methodsForType[methodName]
                : null;
        }

        private static IDictionary<string, MethodInfo> GetExtensionMethodsForType(Type extendedType)
        {
            // WARNING! Two methods with the same name won't work here
            // for sake of example I ignore this fact
            // but you'll have to do something with that

            return AppDomain.CurrentDomain
                            .GetAssemblies()
                            .Select(asm => GetExtensionMethods(asm, extendedType))
                            .Aggregate((a, b) => a.Union(b))
                            .ToDictionary(mi => mi.Name, mi => mi);
        }

        private static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly, Type extendedType)
        {
            var query = from type in assembly.GetTypes()
                        where type.IsSealed && !type.IsGenericType && !type.IsNested
                        from method in type.GetMethods(BindingFlags.Static
                            | BindingFlags.Public | BindingFlags.NonPublic)
                        where method.IsDefined(typeof(ExtensionAttribute), false)
                        where method.GetParameters()[0].ParameterType == extendedType
                        select method;
            return query;
        }
    }

    // example: class with extension methods


    public static class ExtensionMethods
    {
        public static string MyExtensionMethod(this string myString)
        {
            return "ranextension on string '" + myString + "'";
        }
    }

    // example: usage

    internal class Program
    {
        private static void Main()
        {
            var mi = ExtensionMethodsHelper.GetExtensionMethodOrNull(typeof(string), "MyExtensionMethod");
            if (mi != null)
            {
                Console.WriteLine(mi.Invoke(null, new object[] { "hello world" }));
            }
            else
            {
                Console.WriteLine("did't find extension method with name " + "MyExtensionMethod");
            }
        }
    }

更新资料
让我们来看这段代码:
myTest.HasMethodOrExtensionMethod(“ MyExtensionMethod”)吗? myTest.MyExtensionMethod():“ didnotrun”

它不会编译.如何使其工作.

  // utility code
  public static class ExtensionMethods
  {
      public static string MyExtensionMethod(this string myString)
      {
          return "ranextension on string '" + myString + "'";
      }

      public static object InvokeExtensionMethod(this object instance, string methodName, params object[] arguments)
      {
          if (instance == null) throw new ArgumentNullException("instance");

          MethodInfo mi = ExtensionMethodsHelper.GetExtensionMethodOrNull(instance.GetType(), methodName);
          if (mi == null)
          {
              string message = string.Format("Unable to find '{0}' extension method in '{1}' class.", methodName, instance);
              throw new InvalidOperationException(message);
          }

          return mi.Invoke(null, new[] { instance }.Concat(arguments).ToArray());
      }
  }

  // example usage    
  Console.WriteLine("hey".InvokeExtensionMethod("MyExtensionMethod"));

标签:generics,extension-methods,c
来源: https://codeday.me/bug/20191029/1960696.html