2012-02-23 76 views
4

我有這樣的例子的接口姓名(或名稱):現在獲取的接口方法強類型

Interface IRequest{ 

    List<profile> GetProfiles(); 
    void SetProfile (Profile p); 
} 

,在一些日誌記錄組件,我沒有獲得實現接口的對象,但我想在界面中使用方法的名稱。 我當然可以鍵入他們作爲一個字符串(複製方法名稱的字符串),但我想用它們強類型,所以我不必保持方法名稱和字符串同步。

在僞代碼,我會做到這一點:

string s= IRequest.GetProfiles.ToString() 

這是一個可能的方式?

編輯:

也許我應該把它叫做:使用該接口就像是一個枚舉 字符串s = IRequest.GetProfiles.ToString()

+0

你確實有一個對象的實例? – Paddy 2012-02-23 11:32:58

+0

不知道你的越來越強類型的方法名是什麼意思?你如何虛弱或強烈地鍵入一種方法?你想利用代表嗎? – BoltClock 2012-02-23 11:33:45

+0

@ Paddy。是的,我有一個對象的實例,但不是在日誌級別。如果我在那裏得到它會有幫助嗎? – Michel 2012-02-23 11:35:10

回答

6

您可以通過兩種方式實現:

//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() 

然後:

foreach(Type iface in interfaces) 
{ 
    var methods = iface.GetMethods(); 

    foreach(MethodInfo method in methods) 
    {   
     var methodName = method.Name; 
    } 
} 
1

你的問題是有點硬到g韓方。我想你想記錄的實例類或方法的名稱...

如果你想強打字,我認爲你需要使用反射。當然,你可以添加一個字符串名稱可以記錄每個類但這是脆弱的代碼,有人稍後會恨你。你看這種風格在語言不容易支持反射,但我建議不要在像C#語言。

所以解決方案: 您的日誌記錄方法是從實例內部調用的嗎?如果是這樣,我們就可以使用反射來獲取調用方法和許多其他信息的名稱。

如果是的話,那麼這樣的事情可能會爲你工作:

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); 
     } 
} 

這個堆棧溢出問題可能會有所幫助: How I can get the calling methods in C#

這個網站有代碼片段,這兩個重要的線是基於: http://www.csharp-examples.net/reflection-calling-method-name/

1

這是我取得的最好,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

我見過很多viriances這個問題,所以我已經封裝它在一個Q&A後,在這裏 - http://stackoverflow.com/questions/32310767/c-sharp-how-to-get-the-name-的-的接口屬性-FUNC - 動作 - 在-A-strongl – ShloEmi 2015-08-31 13:35:22

2

有時候你不知道事先的類名,那麼你可以使用:

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

然後:

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

請務必檢查方法不爲空幷包含至少一個元素。