Get the name(s) of interface methods strong typed

后端 未结 5 1715
伪装坚强ぢ
伪装坚强ぢ 2020-12-21 02:11

i have an interface like this example:

Interface IRequest{

  List GetProfiles();
  void SetProfile (Profile p);
}

Now, in s

相关标签:
5条回答
  • 2020-12-21 02:35

    This is the best I achieved, HTH:

    using System;
    using System.Collections.Generic;
    using System.Runtime.Remoting.Messaging;
    using System.Runtime.Remoting.Proxies;
    
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace DotNetSandbox
    {
        // Subject interface to get names from
        interface IRequest
        {
            List<object> GetProfiles();
            void SetProfile(object p);
        }
    
        // Use case / Example:
        [TestClass]
        public class InterfaceNamesTests
        {
            [TestMethod]
            public void InterfaceNamesTest()
            {
                // Option 1 - Not strongly typed
                string name = typeof(IRequest).GetMethod("GetProfiles").Name;
                Console.WriteLine(name);    // OUTPUT: GetProfiles
    
                // Option 2 - Strongly typed!!
                var @interface = InterfaceNames<IRequest>.Create();
    
                Func<List<object>> func = @interface.GetProfiles;
                var name1 = func.Method.Name;
                Console.WriteLine(name1);   // OUTPUT: GetProfiles
    
                Action<object> action = @interface.SetProfile;
                var name2 = action.Method.Name;
                Console.WriteLine(name2);   // OUTPUT: SetProfile
    
                // Other options results with complex/unclear code.
            }
        }
    
        // Helper class
        public class InterfaceNames<T> : RealProxy
        {
            private InterfaceNames() : base(typeof(T)) { }
    
            public static T Create()
            {
                return (T)new InterfaceNames<T>().GetTransparentProxy();
            }
    
            public override IMessage Invoke(IMessage msg)
            {
                return null;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-21 02:49

    Your question is a bit hard to grok. I think you want to log the name of the instance class or method...

    If you want strong typing, I think you need to use reflection. You could of course add a string name to each class that can be logged but that is brittle code and someone later on will hate you for it. You see this style in languages that don't easily support reflection but I'd recommend against that in a language like C#.

    So on to a solution: Is your logging method called from inside the instance? If so, we can use reflection to get the name of the calling method and lots of other information.

    If yes, then something like this might work for you:

    class MyRequest: IRequest {
        // other interface implementation details omitted
        public void SetProfiles(Profile p) {
          if(HasUglyPicture(p)) {
             MyLogger.LogError(String.Format(
                     "User {0} update attempted with ugly picture", p.UserName)
             throw new Exception("Profile update failed due to ugly picture!");
         }
     }
    
     class MyLogger : ILogger {
          // other logger details omitted
          public void LogError(string errorMsg) {
              // here's where you get the method name 
              // http://www.csharp-examples.net/reflection-calling-method-name/              
              StackTrace stackTrace = new StackTrace();
              MyLogOutputStream.Write(stackTrace.GetFrame(1).GetMethod().Name);
              MyLogOutputStream.WriteLine(errorMsg);
          } 
     }
    

    This stack overflow question might help: How I can get the calling methods in C#

    This website has the code snippet that the two important lines are based on: http://www.csharp-examples.net/reflection-calling-method-name/

    0 讨论(0)
  • 2020-12-21 02:50

    You can achieve this in two ways:

    //If you CAN access the instance
    var instance = new YourClass(); //instance of class implementing the interface
    var interfaces = instance.GetType().GetInterfaces();
    
    //Otherwise get the type of the class
    var classType = typeof(YourClass); //Get Type of the class implementing the interface
    var interfaces = classType.GetInterfaces()
    

    And then:

    foreach(Type iface in interfaces)
    {
        var methods = iface.GetMethods();
    
        foreach(MethodInfo method in methods)
        {        
            var methodName = method.Name;
        }
    }
    
    0 讨论(0)
  • 2020-12-21 02:53

    Sometimes you don't know the class name in advance, then you can use:

    var interfaceType = typeof(InterfaceName);
    var methods = interfaceType.GetMethods();
    

    and then:

    List<String> methodNames = new List<String>();
    foreach(var method in methods)
    {
        methodNames.Add(method.Name);
    }
    

    Be sure to check if the method is not null and contains at least one element.

    0 讨论(0)
  • 2020-12-21 02:55

    you can use this

    nameof(Interface.Method)

    it's simple

    0 讨论(0)
提交回复
热议问题