Как получить название класса - PullRequest
3 голосов
/ 03 декабря 2008

Хорошо, у меня есть следующая структура. В основном архитектура плагина

// assembly 1 - Base Class which contains the contract
public class BaseEntity {
  public string MyName() {
    // figure out the name of the deriving class
    // perhaps via reflection
  }
}

// assembly 2 - contains plugins based on the Base Class
public class BlueEntity : BaseEntity {}
public class YellowEntity : BaseEntity {}
public class GreenEntity : BaseEntity {}


// main console app
List<BaseEntity> plugins = Factory.GetMePluginList();

foreach (BaseEntity be in plugins) {
  Console.WriteLine(be.MyName);
}

Я бы хотел заявление

be.MyName

, чтобы сказать мне, является ли объект BlueEntity, YellowEntity или GreenEntity. Важно то, что свойство MyName должно быть в базовом классе, потому что я не хочу переопределять свойство в каждом плагине.

Возможно ли это в C #?

Ответы [ 6 ]

10 голосов
/ 03 декабря 2008

Я думаю, вы можете сделать это через GetType:

public class BaseEntity {
    public string MyName() {
        return this.GetType().Name
    }
}
5 голосов
/ 03 декабря 2008
public class BaseEntity {
  public string MyName() {
     return this.GetType().Name;
  }
}

«this» будет указывать на производный класс, так что если вы должны были сделать:

BaseEntity.MyName
"BaseEntity"

BlueEntitiy.MyName
"BlueEntity"

РЕДАКТИРОВАТЬ: Doh, Горький избил меня до этого.

2 голосов
/ 03 декабря 2008

C # реализован способ просмотра объектов, который называется Reflection. Это может вернуть информацию об объекте, который вы используете.

Функция GetType () возвращает имя класса, которому вы ее вызываете. Вы можете использовать это так:

return MyObject.GetType().Name;

Отражение может многое сделать. Если вы хотите больше узнать об рефлексии, вы можете прочитать об этом на этих сайтах:

1 голос
/ 03 декабря 2008

Измените оператор foreach на следующий

foreach (BaseEntity be in plugins) {
   Console.WriteLine(be.GetType().Name);
}
0 голосов
/ 03 декабря 2008

Если вы не переопределили метод ToString () для класса, вы можете просто написать следующее

string s = ToString().Split(',')[0];  // to get fully qualified class name... or,
s = s.Substring(s.LastIndexOf(".")+1); // to get just the actual class name itself

с использованием вашего кода года:

// assembly 1 - Base Class which contains the contractpublic class BaseEntity 
  {  
      public virtual string MyName  // I changed to a property
      {    
          get { return MyFullyQualifiedName.Substring(
               MyFullyQualifiedName.LastIndexOf(".")+1); }
      }
       public virtual string MyFullyQualifiedName  // I changed to a property
      {    
          get { return ToString().Split(',')[0]; }
      }
 }
// assembly 2 - contains plugins based on the Base Class
 public class BlueEntity : BaseEntity {}
 public class YellowEntity : BaseEntity {}
 public class GreenEntity : BaseEntity {}
 // main console app
  List<BaseEntity> plugins = Factory.GetMePluginList();
  foreach (BaseEntity be in plugins) 
     {  Console.WriteLine(be.MyName);}
0 голосов
/ 03 декабря 2008

Попробуйте этот шаблон

class BaseEntity {
  private readonly m_name as string;
  public Name { get { return m_name; } }
  protected BaseEntity(name as string) {
    m_name = name;
  }
}
class BlueEntity : BaseEntity {
  public BlueEntity() : base(typeof(BlueEntity).Name) {}
}
...