2010-09-13 72 views
2

檢索自定義類名的最佳方法是什麼?我的目標是使用描述如下我的課的每一個變化的枚舉脫身:Display Custom Class Name

enum 
{ 
    MyDataType1, 
    MyDataType2, 
    MyDataType3 
} 

每一類可實現如下:

MyDataType1 : IGenericDataType 
MyDataType2 : IGenericDataType 
//etc... 

不過,我有時需要顯示每個班級類型的用戶友好名稱。在我能從枚舉中得到這個之前,但現在我想盡可能從類元數據中獲得它。所以,而不是MyDataType1.GetType()。名稱,它將顯示類名我想使用自定義名稱(無需在類中定義一個屬性)。

+0

爲什麼你反對在基類上創建一個抽象屬性,該屬性提供了描述該類型的用戶自定義字符串?這似乎是最自然和最簡單的方法。你在另一個答案中說,你說你不想要「一堆額外的步驟」。那麼,創建一個新類的人將不得不在某處提供這個字符串,如果它將在那裏。爲什麼不簡單明瞭? '公共抽象字符串UserFriendlyTypeName {get; }' – 2010-09-13 20:12:52

+0

@Jeffery - 我認爲原因是因爲他試圖根據加載的類以外的名稱來動態加載他的類。首先創建該名稱而不創建類的實例是覆蓋ToString()或添加其他屬性不是最優的原因的關鍵。 – Doug 2010-09-14 17:54:43

回答

5

您是否考慮過將類的自定義屬性添加到可以通過反射檢索的類中。 Here is Microsoft's quick tutorial to give you an idea how to apply this technique.使用此方法將允許您通過使用內置框架屬性或定義您自己的內容來根據需要添加儘可能多的附加元數據。

Here is another post that I made that also refers to using extra metadata to do dynamic class loading; which I think is what you are trying to accomplish?

因爲有幾個問題怎麼辦下面這是你可以運行並親眼看到它是如何工作的一個簡單的控制檯應用程序。

享受!

using System; 
using System.Reflection; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Type[] _types = null; 

      //load up a dll that you would like to introspect. In this example 
      //we are loading the currently executing assemble since all the sample code 
      //is constained within this simple program. In practice you may want to change 
      //this to a string that point to a particual assemble on your file system using 
      //Assembly.LoadFrom("some assembly") 
      Assembly a = Assembly.GetExecutingAssembly(); 

      //get an arrray of the types contained in the dll 
      _types = a.GetTypes(); 

      //loop through the type contained in the assembly looking for 
      //particuar types. 
      foreach (Type t in _types) 
      { 
       //see if this type does not contain the desired interfaec 
       //move to the next one. 
       if (t.GetInterface("CustomInterface") == null) 
       { 
        continue; 
       } 

       //get a reference to the attribute 
       object[] attributes = t.GetCustomAttributes(typeof(CustomAttribute), false); 
       CustomAttribute attribute = (CustomAttribute)attributes[0]; 

       //do something with the attribue 
       Console.WriteLine(attribute.Name); 
      } 
     } 
    } 


    /// <summary> 
    /// This is a sample custom attribute class. Add addtional properties as needed! 
    /// </summary> 
    public class CustomAttribute : Attribute 
    { 
     private string _name = string.Empty; 

     public CustomAttribute(string name) 
      : base() 
     { 
      _name = name; 
     } 

     public string Name 
     { 
      get 
      { 
       return _name; 
      } 
      set 
      { 
       _name = value; 
      } 
     } 
    } 

    /// <summary> 
    /// Here is a custom interface that we can search for while using reflection. 
    /// </summary> 
    public interface CustomInterface 
    { 
     void CustomMethod(); 
    } 

    /// <summary> 
    /// Here is a sample class that implements our custom interface and custom attribute. 
    /// </summary> 
    [CustomAttribute("Some string I would like to assiciate with this class")] 
    public class TestClass : CustomInterface 
    { 
     public TestClass() 
     { 
     } 

     public void CustomMethod() 
     { 
      //do some work 
     } 
    } 

    /// <summary> 
    /// Just another class without the interface or attribute so you can see how to just 
    /// target the class you would like by the interface. 
    /// </summary> 
    public class TestClass2 
    { 
     public TestClass2() 
     { 
     } 

     public void CustomMethod() 
     { 
      //do some work 
     } 
    } 
} 
+0

我曾想過一個自定義屬性。我不知道是否有更簡單的方法來做到這一點。 – 2010-09-13 19:00:59

+0

@Blake - 我不知道一個簡單的方法,可以將元數據與您的班級直接綁定。我已經使用了動態類加載類型的風景技術。國際海事組織我認爲它會爲你想要完成的工作做好。 – Doug 2010-09-13 19:03:35

+0

也在考慮這一點,但檢索這個名字真的很痛苦。 – MrFox 2010-09-13 19:09:52

0

如果你不想在類中定義一個屬性,那麼你必須創建一些查找表,將類名映射到友好名稱。除非你可以從班級名稱中派生出友好的名字。即「ManagementEmployeeClass」具有「管理員工」的友好名稱,或者類別名稱「IT_Contract_Worker」變爲「IT合同工」。

+0

我很害怕這個。看起來這樣做會挫敗我的目標,即允許實現IGenericDataType的新類插入,而無需瞭解一些額外的步驟。 – 2010-09-13 19:01:43

2

什麼重寫的ToString()屬性:

var x = MyCustomClass(); 
Console.WriteLine(x.ToString(); 


public class MyCustomClass() 
{ 
    public override string ToString() 
    { 
     return "MyCustom Class user friendly name"; 
    } 
} 
1

我會用一個自定義屬性做到這一點。

你只是在你的類創建一個類

[AttributeUsage(AttributeTargets.Class] 
Class SimpleClassName : System.Attribute{ 
    public string ClassName { get; set; } 

    SimpleClassName(string _name){ 
    ClassName = _name; 
    } 

} 

然後你只需要獲得自定義後該屬性值,那麼你就

[SimpleClassName("Easy")] 
Class ComplicatedName{ 

} 

我是一個VB程序員網在白天忽略壞C#