• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#中Property和Attribute的区别实例详解

C#中Property和Attribute的区别实例详解

作者:春哥也编程 字体:[增加 减小] 来源:互联网 时间:2017-05-28

春哥也编程 通过本文主要向大家介绍了attribute和property,c#中propertygrid使用,c#property,c#propertygrid,c#attribute等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文实例分析了C#中Property和Attribute的区别。分享给大家供大家参考。具体分析如下:

在C#中有两个属性,分别为Property和Attribute,两个的中文意思都有特性、属性之间,但是用法上却不一样,为了区别,本文暂把Property称为特性,把Attribute称为属性。

Attribute才是本文的主角,把它称为属性我觉得很恰当。属性的意思就是附属于某种事物上的,用来说明这个事物的各种特征的一种描述。而Attribute就是干这事的。它允许你将信息与你定义的C#类型相关联,作为类型的标注。这些信息是任意的,就是说,它不是由语言本身决定的,你可以随意建立和关联任何类型的任何信息。你可以作用属性定义设计时信息和运行时信息,甚至是运行时的行为特征。关键在于这些信息不仅可以被用户取出来作为一种类型的标注,它更可以被编译器所识别,作为编译时的一种附属条件参加程序的编译。

以下部分内容及代码来源于《C#技术揭秘》(Inside C# Sencond Edition)

定义属性:

属性实际上是一个派生自System.Attribute基类的类。System.Attribute类含有几个用于访问和检查自定义属性的方法。尽管你有权将任何类定义为属性,但是按照惯例来说,从System.Attribute派生类是有意义的。示例如下:

public enum RegHives
{
   HKEY_CLASSES_ROOT,
   HKEY_CURRENT_USER,
   HKEY_LOCAL_MACHINE,
   HKEY_USERS,
   HKEY_CURRENT_CONFIG
}
public class RegKeyAttribute : Attribute
{
   public RegKeyAttribute(RegHives Hive, String ValueName)
   {
    this.Hive = Hive;
    this.ValueName = ValueName;
   }
   protected RegHives hive;
   public RegHives Hive
   {
    get { return hive; }
    set { hive = value; }
   }
   protected String valueName;
   public String ValueName
   {
    get { return valueName; }
    set { valueName = value; }
   }
}

</div>

我们在这里添加了不同注册表的枚举、属性类的构造器以及两个特性(Property)。在定义属性时你可以做许许多多的事情,下面我们看看如何在运行时查询属性。要想在运行时查询类型或成员所附着的属性,必须使用反射

查询类属性:

假设你希望定义一个属性,这个属性定义了将在其上创建对象的远程服务器。如果没有这个属性,就要把此信息保存在一个常量中或是一个应用程序的资源文件中。通过使用属性,只需用以下方法标注出类的远程服务器名即可:

using System;
namespace QueryAttribs
{
  public enum RemoteServers
  {
   JEANVALJEAN,
   JAVERT,
   COSETTE 
  }
  public class RemoteObjectAttribute : Attribute
  {
   public RemoteObjectAttribute(RemoteServers Server)
   {
    this.server = Server;
   }
   protected RemoteServers server;
   public string Server
   {
    get
    {
     return RemoteServers.GetName(
      typeof(RemoteServers), this.server);
    }
   }
  }
  [RemoteObject(RemoteServers.COSETTE)]
  class MyRemotableClass
  {
  }
  class Test
  {
   [STAThread]
   static void Main(string[] args)
   {
    Type type = typeof(MyRemotableClass);
    foreach (Attribute attr in
     type.GetCustomAttributes(true))
    {
     RemoteObjectAttribute remoteAttr =
      attr as RemoteObjectAttribute;
     if (null != remoteAttr)
     {
     Console.WriteLine(
       "Create this object on {0}.",
       remoteAttr.Server);
     }
    }
    Console.ReadLine();
   }
  }
}
</div>

运行结果为:

Creat this object on COSETTE。

注意:在这个例子中的属性类名具有Attribute后缀。但是,当我们将此属性附着给类型或成员时却不包括Attribute后缀。这是C#语言的设计者提供的简单方式。当编译器看到一个属性被附着给一个类型或成员时,它会搜索具有指定属性名的System.Attribute派生类。如果编译器没有找到匹配的类,它就在指定的属性名后面加上Attribute,然后再进行搜索。因此,常见的使用做法是将属性类名定义为以Attribute结尾,在使用时忽略名称的这一部分。以下的代码都采用这种命名方式。

查询方法属性:

在下面这个例子中,我们使用属性将方法定义为可事务化的方法,只要存在TransactionableAttribute属性,代码就知道具有这个属性的方法可以属于一个事务。

using System;
using System.Reflection;
namespace MethodAttribs
{
  public class TransactionableAttribute : Attribute
  {
   public TransactionableAttribute()
   {
   }
  }
  class SomeClass
  {
   [Transactionable]
   public void Foo()
   {}
   public void Bar()
   {}
   [Transactionable]
   public void Goo()
   {}
  }
  class Test
  {
   [STAThread]
   static void Main(string[] args)
   {
    Type type = Type.GetType("MethodAttribs.SomeClass");
    foreach (MethodInfo method in type.GetMethods())
    {
     foreach (Attribute attr in
      method.GetCustomAttributes(true))
     {
      if (attr is TransactionableAttribute)
      {
       Console.WriteLine(
        "{0} is transactionable.",
        method.Name);
      }
     }
    }
    Console.ReadLine();
   }
  }
}
</div>

运行结果如下:

Foo is transactionable.
Goo is transactionable.
 
查询字段属性:

假设有一个类含有一些字段,我们希望将它们的值保存进注册表。为此,可以使用以枚举值和字符串为参数的构造器定义一个属性,这个枚举值代表正确的注册表hive,字符串代表注册表值名称。在运行时可以查询字段的注册表键。

using System;
using System.Reflection;
namespace FieldAttribs
{
  public enum RegHives
  {
   HKEY_CLASSES_ROOT,
   HKEY_CURRENT_USER,
   HKEY_LOCAL_MACHINE,
   HKEY_USERS,
   HKEY_CURRENT_CONFIG
  }
  public class RegKeyAttribute : Attribute
  {
   public RegKeyAttribute(RegHives Hive, String ValueName)
   {
    this.Hive = Hive;
    this.ValueName = ValueName;
   }
   protected RegHives hive;
   public RegHives Hive
   {
    get { return hive; }
    set { hive = value; }
   }
   protected String valueName;
   public String ValueName
   {
    get { return valueName; }
    set { valueName = value; }
   }
  }
  class SomeClass
  {
   [RegKey(RegHives.HKEY_CURRENT_USER, "Foo")]
   public int Foo;
 
   public int Bar;
  }
  class Test
  {
   [STAThread]
   static void Main(string[] args)
   {
    Type type = Type.GetType("FieldAttribs.SomeClass");
    foreach (FieldInfo field in type.GetFields())
    {
     foreach (Attribute attr in
      field.GetCustomAttributes(true))
     {
      RegKeyAttribute rka =
       attr as RegKeyAttribute;
      if (null != rka)
      {
       Console.WriteLine(
        "{0} will be saved in"
        + " {1}\\\\{2}",
        field.Name,
        rka.Hive,
        rka.ValueName);
      }
     }
    }
    Console.ReadLine();
   }
  }
}
</div>

运行结果为:

Foo will be saved in HKEY_CURRENT_USER\\Foo

大家可以看到,用属性来标注类、方法、字段,既可以把用户的自定义信息附属在实体上,又可以在运行时动态的查询。下面我将讲一些C#中默认的预定义属性,见下表:

预定义的属性 有效目标 说明
AttributeUsage Class 指定另一个属性类的有效使用方式
CLSCompliant 全部 指出程序元素是否与CLS兼容
Conditional Method 指出如果没有定义相关联的字符串,编译器就可以忽略对这个方法的任何调用
DllImport Method 指定包含外部方法的实现的DLL位置
STAThread Method(Main) 指出程序的默认线程模型为STA
MTAThread Method(Main) 指出程序的默认模型为多线程(MTA)
Obsolete 除了Assembly、Module、Parameter和Return 将一个元素标示为不可用,通知用户此元素将被从未来的产品
ParamArray Parameter 允许单个参数被隐式地当作params(数组)参数对待
Serializable Class、Struct、enum、delegate 指定这种类型的所有公共和私有字段可以被串行化
NonSerialized Field 应用于被标示为可串行化的类的字段,指出这些字段将不可被串行化
StructLayout Class、struct 指定类或结构的数据布局的性质,比如Auto、Explicit或sequential
ThreadStatic Field(静态) 实现线程局部存储(TLS)。不能跨多个线程共享给定的静态字段,每个线程拥有这个静态字段的副本

下面介绍几种常用的属性

1.[STAThread]和[MTAThread]属性

class Class1
{
  [STAThread]
  Static void Main( string[] args )
  {
  }
}<



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C#中Property和Attribute的区别实例详解

相关文章

  • 2017-05-28简单实现C#异步操作
  • 2017-05-28C#彩色图片灰度化算法实例
  • 2017-05-28AjaxControlToolkit AjaxFileUpload 显示英文改成中文的解决方法
  • 2017-05-28c#多线程中Lock()关键字的用法小结
  • 2017-05-28C#遍历操作系统下所有驱动器的方法
  • 2017-05-28DevExpress实现TreeList按条件隐藏节点CheckBox的方法
  • 2017-05-28c#二维码生成的代码分享
  • 2017-05-28C#中分部方法和分部类分析
  • 2017-05-28C#枚举中的位运算权限分配浅谈
  • 2017-05-28c# yield提高代码性能和可读性

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 学习C#静态函数及变量的一个精典例子与代码
    • 使用C#发送Http请求实现模拟登陆实例
    • C#如何动态设置屏幕分辨率
    • .Net Winform开发笔记(四)透过现象看本质
    • C#绘制飞行棋地图小程序
    • Windows窗体的.Net框架绘图技术实现方法
    • C#实现winform中RichTextBox在指定光标位置插入图片的方法
    • 解析XPath语法之在C#中使用XPath的示例详解
    • 轻松学习C#的异常处理
    • c#静态方法和非静态方法详细介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有