【问题标题】:C# property attributesC# 属性属性
【发布时间】:2010-09-17 13:06:33
【问题描述】:

我看过以下代码:

[DefaultValue(100)]
[Description("Some descriptive field here")]
public int MyProperty{...} 

上述代码段的功能似乎很清楚,我不知道如何使用它来做有用的事情。我什至不确定要给它起什么名字!

有谁知道我在哪里可以找到有关这些属性属性的更多信息/教程? 我也会对此功能可以执行的任何新颖/有用的任务感兴趣。

【问题讨论】:

    标签: c# properties attributes


    【解决方案1】:

    这些属性自定义设计时体验。

    http://msdn.microsoft.com/en-us/library/a19191fh.aspx

    【讨论】:

      【解决方案2】:

      视觉设计器(即 MS Expression Blend 和 Visual Studio 设计器)使用您示例中的那些在设计器 UI 中提供提示。

      请注意,它们是元数据,不会影响属性逻辑。例如,设置 DefaultValue 默认不会将该属性设置为该值,您必须手动进行。

      如果您出于某种原因想要访问这些属性,则必须use reflection

      有关设计师属性的更多信息,请参阅MSDN

      【讨论】:

      • 它们也用于 Visual Studio 设计器。
      • 重要的是要注意它们只是提示:例如,您仍然必须在代码中将 MyPperty 的默认值设置为 100,否则您最终会对您的财产的消费者撒谎。
      【解决方案3】:

      它们被称为属性,在msdn中有很多信息,例如http://msdn.microsoft.com/en-us/library/z0w1kczw.aspx

      一般来说,它们不会自己“做”任何事情,它们会被其他一些将使用您的类的代码使用。 XmlSerialization 就是一个很好的例子:XmlSerializer(由 Microsoft 作为框架的一部分提供)几乎可以用于任何类(尽管对类有很多要求)——它使用反射来查看类中包含哪些数据。您可以使用属性(与 XmlSerializer 一起定义)来更改 XmlSerializer 序列化您的类的方式(例如,告诉它将数据保存为属性而不是元素)。

      【讨论】:

        【解决方案4】:

        上述功能 片段看起来很清楚,

        也许不是,因为许多人认为 [DefaultValue()] 设置 属性的值。实际上,它所做的一切都是为了告诉一些视觉设计师(例如 Visual Studio),代码会将默认值设置为什么。这样它就知道如果属性窗口中的值设置为其他值,则将其加粗

        【讨论】:

        • 所以如果我没有明确地将 MyProperty 设置为另一个值,表单设计器(或等效的)会在后台将 MyProperty 设置为 100?
        • 不!如果您没有将 MyProperty 显式设置为一个值,它将默认为 0(假设一个后备存储)。表单设计器会将值显示为“0”,但以粗体显示,表示已手动更改默认值。如果只影响表单设计器中值的外观。
        【解决方案5】:

        人们已经介绍了 UI 方面 - 属性还有其他用途,但是……例如,它们在大多数序列化框架中被广泛使用。 编译器对某些属性进行了特殊处理 - 例如,[PrincipalPermission(...)] 为方法添加声明性安全性,允许您(自动)检查用户是否具有适当的访问权限。

        要添加自己的特殊处理,可以使用PostSharp;有很多使用 PostSharp 做 AOP 事情的好例子,比如日志记录——或者只是代码简化,比如 automatic INotifyPropertyChanged implementation

        【讨论】:

          【解决方案6】:

          我们用它来定义应该加载哪个图形设计器来配置 特定类型的实例。

          也就是说,我们有一种工作流设计器,它可以加载所有可能的命令 来自程序集的类型。这些命令类型具有需要配置的属性, 因此每种命令类型都需要不同的设计器(用户控件)。

          例如,考虑以下命令类型(在我们的解决方案中称为复合)

          [CompositeMetaData("Delay","Sets the delay between commands",1)]
          [CompositeDesigner(typeof(DelayCompositeDesigner))]
          public class DelayComposite : CompositeBase 
          {
                 // code here
          }
          

          这是在两个地方使用的信息

          1) 当设计器创建命令列表时,它使用 CompositeMetaData 显示有关该命令的更多信息。

          2) 当用户向设计器添加命令并且设计器创建 该类的一个实例,它查看 CompositeDesigner 属性, 创建指定类型(用户控件)的新实例并添加它 给视觉设计师。

          考虑以下代码,我们用于将命令加载到我们的“工具栏”中:

          foreach (Type t in assembly.GetExportedTypes())  
          {
              Console.WriteLine(t.Name);
          
              if (t.Name.EndsWith("Composite"))
              {
                  var attributes = t.GetCustomAttributes(false);
                  ToolboxListItem item = new ToolboxListItem();
          
                  CompositeMetaDataAttribute meta = (CompositeMetaDataAttribute)attributes
                                        .Where(a => a.GetType() == typeof(Vialis.LightLink.Attributes.CompositeMetaDataAttribute)).First();
                  item.Name = meta.DisplayName;
                  item.Description = meta.Description;
                  item.Length = meta.Length;
                  item.CompositType = t;
          
                  this.lstCommands.Items.Add(item);
              }                           
          }
          

          如您所见,对于名称以“Composite”结尾的程序集中的每种类型, 我们获取自定义属性并使用该信息来填充我们的 ToolboxListItem 实例。

          至于加载设计器,属性是这样检索的:

          var designerAttribute = (CompositeDesignerAttribute)item.CompositType.GetCustomAttributes(false)
                                   .Where(a => a.GetType() == typeof(CompositeDesignerAttribute)).FirstOrDefault();
          

          这只是您可以如何使用自定义属性的一个示例,

          我希望这能给你一个开始的地方。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-29
            • 2017-05-31
            相关资源
            最近更新 更多