2010-09-13 71 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#