2013-04-28 3 views
13

У меня есть абстрактный базовый класс, где я хотел бы реализовать метод, который будет извлекать свойство атрибута наследующего класса. Что-то вроде этого ...Как получить `Тип` подкласса из базового класса

public abstract class MongoEntityBase : IMongoEntity { 

    public virtual object GetAttributeValue<T>(string propertyName) where T : Attribute { 
     var attribute = (T)typeof(this).GetCustomAttribute(typeof(T)); 
     return attribute != null ? attribute.GetType().GetProperty(propertyName).GetValue(attribute, null) : null; 
    } 
} 

И Реализовано вот так ...

[MongoDatabaseName("robotdog")] 
[MongoCollectionName("users")] 
public class User : MonogoEntityBase { 
    public ObjectId Id { get; set; } 

    [Required] 
    [DataType(DataType.EmailAddress)] 
    public string email { get; set; } 

    [Required] 
    [DataType(DataType.Password)] 
    public string password { get; set; } 

    public IEnumerable<Movie> movies { get; set; } 
} 

Но, конечно, с выше коде GetCustomAttribute() не является доступным методом, потому что это не конкретный класс.

Что необходимо сделать для typeof(this) в абстрактном классе, чтобы иметь доступ к классу наследования? Или это не хорошая практика, и должен ли я реализовать метод в классе наследования вообще?

+1

Не следует ли «Пользователь» наследовать от «MongoEntityBase»? –

+0

Вы правы, спасибо. я починил это – bflemi3

ответ

13

Вы должны использовать this.GetType(). Это даст вам фактический конкретный тип экземпляра.

Так что в этом случае:

public virtual object GetAttributeValue<T>(string propertyName) where T : Attribute { 
    var attribute = this.GetType().GetCustomAttribute(typeof(T)); 
    return attribute != null ? attribute.GetType().GetProperty(propertyName).GetValue(attribute, null) : null; 
} 

Обратите внимание, что он возвращает самый верхний класс. То есть, если у вас:

public class AdministrativeUser : User 
{ 

} 

public class User : MongoEntityBase 
{ 

} 

Тогда this.GetType() вернется AdministrativeUser.


Кроме того, это означает, что вы могли бы реализовать метод GetAttributeValue вне abstract базового класса. Вам не потребовалось бы, чтобы исполнители наследовали от MongoEntityBase.

public static class MongoEntityHelper 
{ 
    public static object GetAttributeValue<T>(IMongoEntity entity, string propertyName) where T : Attribute 
    { 
     var attribute = (T)entity.GetType().GetCustomAttribute(typeof(T)); 
     return attribute != null ? attribute.GetType().GetProperty(propertyName).GetValue(attribute, null) : null; 
    } 
} 

(также может реализовать его в качестве метода расширения, если вы хотите)

4

typeof(this) не будет компилироваться.

Что вы ищете? this.GetType().

Смежные вопросы