代码之家  ›  专栏  ›  技术社区  ›  Gareth

获取作为基类传递给泛型方法的派生C#类的属性

  •  8
  • Gareth  · 技术社区  · 11 年前

    当派生类的属性通过基类参数传递到方法中时,我试图确定该属性的值。

    例如,完成下面的代码示例:

    class Program
    {
        static void Main(string[] args)
        {
            DerivedClass DC = new DerivedClass();
            ProcessMessage(DC);
        }
    
        private static void ProcessMessage(BaseClass baseClass)
        {
            Console.WriteLine(GetTargetSystemFromAttribute(baseClass));
            Console.ReadLine();
        }
    
        private static string GetTargetSystemFromAttribute<T>(T msg)
        {
            TargetSystemAttribute TSAttribute = (TargetSystemAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(TargetSystemAttribute));
    
            if (TSAttribute == null)
                throw new Exception(string.Format("Message type {0} has no TargetSystem attribute and/or the TargetSystemType property was not set.", typeof(T).ToString()));
    
            return TSAttribute.TargetSystemType;
        }
    }
    
    public class BaseClass
    {}
    
    [TargetSystem(TargetSystemType="OPSYS")]
    public class DerivedClass : BaseClass
    {}
    
    [AttributeUsage(AttributeTargets.Class)]
    public sealed class TargetSystemAttribute : Attribute
    {
        public string TargetSystemType { get; set; }
    }
    

    因此,在上面的例子中,我本来打算 从属性获取目标系统 方法返回“OPSYS”。

    但是,因为DerivedClass实例已传递给 处理消息 作为基类, 属性.GetAttribute 找不到任何东西,因为它将DerivedClass视为基类,而基类没有我感兴趣的属性或值。

    在现实世界中有几十个派生类,所以我希望避免很多:

    if (baseClass is DerivedClass)
    

    …这是问题中的答案 How to access the properties of an instance of a derived class which is passed as a parameter in the form of the base class (与类似问题有关,但与财产有关)。我希望,因为我对Attributes感兴趣,所以有更好的方法来做这件事,尤其是因为我有几十个派生类。

    所以,问题来了。有什么方法可以以低维护的方式获得派生类上TargetSystem属性的TargetSystemType值吗?

    1 回复  |  直到 7 年前
        1
  •  9
  •   Lev    11 年前

    您应该更改这一行:

    (TargetSystemAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(TargetSystemAttribute));
    

    这样:

    msg.GetType().GetCustomAttributes(typeof(TargetSystemAttribute), true)[0] as TargetSystemAttribute;
    

    P.S.GetCustomAttributes返回数组,我选择了第一个元素,例如,在只需要1个属性的情况下,您可能需要更改,但逻辑是相同的。