【问题标题】:C# Override an attribute in a subclassC# 覆盖子类中的属性
【发布时间】:2010-10-01 14:39:25
【问题描述】:
public class MyWebControl {

    [ExternallyVisible]
    public string StyleString {get;set;}

}

public class SmarterWebControl : MyWebControl {

    [ExternallyVisible]
    public string CssName{get;set;}

    new public string StyleString {get;set;} //Doesn't work

}

是否可以删除子类中的属性?我确实希望该属性被其他子类继承,而不是这个。

编辑:哎呀,好像我忘了编译什么的,因为上面发布的代码确实有效!

【问题讨论】:

  • 很高兴它有效,我很困惑为什么它不会。不得不说,我不确定我是否喜欢在这里使用 new (虽然我一般来说有点反 - new)。对于看课程的人来说,它并没有告诉他们你为什么这样做。另一方面,使用带有 false 参数的属性是自我记录恕我直言
  • 没错,如果我是从头开始写整件事,我可能会那样做;)

标签: c# attributes


【解决方案1】:

这正是为什么可以“覆盖”的框架属性采用布尔参数(从表面上看)似乎毫无意义的原因。以BrowsableAttribute 为例;从名称来看,布尔参数似乎已经过时了,但举个例子:

class SomeComponent
{
  [Browsable(true)]
  public virtual string SomeInfo{get;set;}
}

class SomeOtherComponent : SomeComponent
{
  [Browsable(false)]  // this property should not be browsable any more
  public override string SomeInfo{get;set;}
}

所以,要回答您的问题,您可以让 ExternallyVisible 属性采用布尔参数,以指示它是否实际上在外部可见,并且当您继承时您可以更改为 false - 就像 BrowsableAttribute

【讨论】:

    【解决方案2】:

    它对我有用。

    测试代码:

    public static void Main()
    {
        var attribute = GetAttribute(typeof (MyWebControl), "StyleString", false);
        Debug.Assert(attribute != null);
    
        attribute = GetAttribute(typeof(SmarterWebControl), "StyleString", false);
        Debug.Assert(attribute == null);
    
        attribute = GetAttribute(typeof(SmarterWebControl), "StyleString", true);
        Debug.Assert(attribute == null);
    }
    
    private static ExternallyVisibleAttribute GetAttribute(Type type, string propertyName, bool inherit)
    {
        PropertyInfo property = type.GetProperties().Where(p=>p.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
    
        var list = property.GetCustomAttributes(typeof(ExternallyVisibleAttribute), inherit).Select(o => (ExternallyVisibleAttribute)o);
    
        return list.FirstOrDefault();
    }
    

    【讨论】:

      【解决方案3】:

      我不明白问题出在哪里。您发布的代码在我的测试中完成了预期的事情(至少,它看起来像您期望的那样):也就是说,StyleString 属性没有ExternallyVisible 属性。这是我的测试代码:

      [AttributeUsage(AttributeTargets.Property)]
      public class ExternallyVisible : Attribute
      {
      }
      
      public class MyWebControl
      {
          [ExternallyVisible]
          public string StyleString { get; set; }
      }
      
      public class SmarterWebControl : MyWebControl
      {
          [ExternallyVisible]
          public string CssName { get; set; }
      
          new public string StyleString { get; set; } // Doesn't work
      }
      
      class Program
      {
          static void Main()
          {
              MyWebControl myctrl = new MyWebControl();
              SmarterWebControl smartctrl = new SmarterWebControl();
      
              MemberInfo info = typeof(SmarterWebControl);
              PropertyInfo[] props = (typeof(SmarterWebControl)).GetProperties();
              Console.WriteLine("{0} properties", props.Length);
      
              foreach (var prop in props)
              {
                  Console.WriteLine(prop.Name);
                  foreach (var attr in prop.GetCustomAttributes(true))
                  {
                      Console.WriteLine("  " + attr);
                  }
              }
      
              Console.ReadLine();
          }
      }
      

      在 .NET 4.0 中,我得到以下输出:

      2 properties
      CssName
        sotesto.ExternallyVisible
      StyleString
      

      换句话说,该属性不适用于StyleString 属性。

      【讨论】:

        【解决方案4】:

        您可以继承该属性并添加一个控制属性代码是否触发的属性。

        那么你可以覆盖继承类的属性行为吗?

        所以你会使用(如果你向构造函数添加了一个参数)

        [ExternallyVisible(false)]
        
        [ExternallyVisible(Enabled = false)]
        

        我在属性类中使用了 enabled 属性

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-19
          • 1970-01-01
          • 2015-09-12
          • 1970-01-01
          • 2015-06-20
          • 1970-01-01
          相关资源
          最近更新 更多