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 )
       {
       }

使用STAThread属性将程序的默认线程模型指定为单线程模型。注意,线程模型只影响使用COM interop的应用程序,将这个属性应用于不使用COM interop的程序将不会产生任何效果。
2. AttributeUsage属性
       除了用于标注常规C#类型的自定义属性以外,还可以使用AttributeUsage属性定义你使用这些属性的方式。文件记录的AttributeUsage属性调用用法如下:
[AttributeUsage( validon , AllowMutiple = allowmutiple , Inherited = inherited )]
Validon参数是AttributeTargets类型的,这个枚举值的定义如下:
public enum AttributeTargets

       Assembly = 0x0001,
       Module = 0x0002,
       Class = 0x0004,
       Struct = 0x0008,
       Enum = 0x0010,
       Constructor = 0x0020,
       Method = 0x0040,
       Property = 0x0080,
       Field = 0x0100,
       Event = 0x200,
       Interface = 0x400,
       Parameter = 0x800,
       Delegate = 0x1000,
       All = Assembly | Module | Class | Struct | Enum | Constructor| Method | Property|                    Filed| Event| Interface | Parameter | Deleagte ,
       ClassMembers = | Class | Struct | Enum | Constructor | Method | Property | Field |                    Event | Delegate | Interface

AllowMultiple决定了可以在单个字段上使用某个属性多少次,在默认情况下,所有的属性都是单次使用的。示例如下:
[AttributeUsage( AttributeTargets.All , AllowMultiple = true )]
public class SomethingAttribute : Attribute

       public SomethingAttribute( string str )
       {
       }

//如果AllowMultiple = false , 此处会报错
[Something(“abc”)]
[Something(“def”)]
class Myclass

Inherited参数是继承的标志,它指出属性是否可以被继承。默认是false。
Inherited AllowMultiple 结果
true false 派生的属性覆盖基属性
true false 派生的属性和基属性共存
代码示例:
using System;
using System.Reflection;

namespace AttribInheritance

    [AttributeUsage(
         AttributeTargets.All,
         AllowMultiple=true,
//       AllowMultiple=false,
         Inherited=true
    )]
    public class SomethingAttribute : Attribute
    {
        private string name;
        public string Name
        {
             get { return name; }
             set { name = value; }
        }

        public SomethingAttribute(string str)
        {
             this.name = str;
        }
    }
       
    [Something("abc")]
    class MyClass
    {
    }

    [Something("def")]
    class Another : MyClass
    {
    }
       
    class Test
    {
        [STAThread]
        static void Main(string[] args)
        {
             Type type =
                 Type.GetType("AttribInheritance.Another");
             foreach (Attribute attr in
                 type.GetCustomAttributes(true))
//                type.GetCustomAttributes(false))
             {
                 SomethingAttribute sa =
                      attr as SomethingAttribute;
                 if (null != sa)
                 {
                 Console.WriteLine(
                          "Custom Attribute: {0}",
                          sa.Name);
                 }
             }

        }
    }

当AllowMultiple被设置为false时,结果为:
Custom Attribute : def
当AllowMultiple被设置为true时,结果为:
Custom Attribute : def
Custom Attribute : abc
注意,如果将false传递给GetCustomAttributes,它不会搜索继承树,所以你只能得到派生的类属性。

3.Conditional 属性
       你可以将这个属性附着于方法,这样当编译器遇到对这个方法调用时,如果没有定义对应的字符串值,编译器就忽略这个调用。例如,以下方法是否被编译取决于是否定义了字符串“DEGUG”:
[Condition(“DEBUG”) ]
public void SomeDebugFunc()

       Console.WriteLine(“SomeDebugFunc”);

using System;
using System.Diagnostics;

namespace CondAttrib

    class Thing
    {
        private string name;
        public Thing(string name)
        {
             this.name = name;
             #if DEBUG
                 SomeDebugFunc();
             #else
                 SomeFunc();
             #endif
        }
        public void SomeFunc()
             { Console.WriteLine("SomeFunc"); }

        [Conditional("DEBUG")]
        [Conditional("ANDREW")]
        public void SomeDebugFunc()
             { Console.WriteLine("SomeDebugFunc"); }
    }

    public class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
             Thing t = new Thing("T1");
        }
    }

4. Obsolete 属性
       随着代码不断的发展,你很可以会有一些方法不用。可以将它们都删除,但是有时给它们加上适当的标注比删除它们更合适,例如:
using System;

namespace ObsAttrib

    class SomeClass
    {
        [Obsolete("Don't use OldFunc, use NewFunc instead", true)]
        public void OldFunc( ) { Console.WriteLine("Oops"); }

        public void NewFunc( ) { Console.WriteLine("Cool"); }
    }

    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
             SomeClass sc = new SomeClass();
             sc.NewFunc();
//            sc.OldFunc();     // compiler error
        }
    }

我们将Obsolete属性的第二个参数设置为true,当调用时函数时编译器会产生一个错误。
E:\InsideC#\Code\Chap06\ObsAttrib\ObsAttrib\Class1.cs(20): 'ObsAttrib.SomeClass.OldFunc()' 已过时: 'Don't use OldFunc, use NewFunc instead'

5. DllImport和StructLayout属性
       DllImport可以让C#代码调用本机代码中的函数,C#代码通过平台调用(platform invoke)这个运行时功能调用它们。
       如果你希望运行时环境将结构从托管代码正确地编组现非托管代码(或相反),那么需要为结构的声明附加属性。为了使结构参数可以被正确的编组,必须使用StructLayout属性声明它们,指出数据应该严格地按照声明中列出的样子进行布局。如果不这么做,数据将不能正确地被编组,而应用程序可能会出错。
using System;
using System.Runtime.InteropServices;    // for DllImport

namespace nativeDLL

    public class Test
    {
//       [DllImport ("user32.dll")]           // all the defaults are OK
        [DllImport("user32", EntryPoint="MessageBoxA",
             SetLastError=true,
             CharSet=CharSet.Ansi, ExactSpelling=true,
             CallingC.StdCall)]
        public static extern int MessageBoxA (
             int h, string m, string c, int type);

        [StructLayout(LayoutKind.Sequential)]
        public class SystemTime {
             public ushort wYear;
             public ushort wMonth;
             public ushort wDayOfWeek;
             public ushort wDay;
             public ushort wHour;
             public ushort wMinute;
             public ushort wSecond;
             public ushort wMilliseconds;
        }

        [DllImport ("kernel32.dll")]
        public static extern void GetLocalTime(SystemTime st);

        [STAThread]
        public static void Main(string[] args)
        {
             MessageBoxA(0, "Hello World", "nativeDLL", 0);

             SystemTime st = new SystemTime();
             GetLocalTime(st);
             string s = String.Format("date: {0}-{1}-{2}",
                 st.wMonth, st.wDay, st.wYear);
             string t = String.Format("time: {0}:{1}:{2}",
                 st.wHour, st.wMinute, st.wSecond);
             string u = s + ", " + t;

             MessageBoxA(0, u, "Now", 0);
        }
    }

6. 配件属性
       当使用.NET产生任何类型的C#工程时,会自动的产生一个AssemblyInfo.cs源代码文件以及应用程序源代码文件。AssemblyInfo.cs中含有配件中代码的信息。其中的一些信息纯粹是信息,而其它信息使运行时环境可以确保惟一的命名和版本号,以供重用你的配件的客户代码使用。

7. 上下文属性
       .NET柜架还提供了另一种属性:上下文属性。上下文属性提供了一种截取机制,可以在类的实例化和方法调用之前和之后进行处理。这种功能用于对象远程调用,它是从基于COM的系统所用的COM+组件服务和Microsoft Transaction Services(MTS)。

C#中一些默认的预定义属性的更多相关文章

  1. linux中位置参数变量和预定义变量

    位置参数变量   预定义变量

  2. C++ 中常见预定义宏的使用

    http://blog.csdn.net/hgl868/article/details/7058906 替代字符串: #define DOWNLOAD_IMAGE_LOG /var/log/png.l ...

  3. visual c++中预定义的宏

    一.主要目标 (由于visual studio通常包含很多开发环境,通常将其中c/c++的ide称为visual c++ 20xx) 整理下visual c++ 2010下预定义的宏.做一下备忘和了解 ...

  4. C标准中一些预定义的宏

    C标准中指定了一些预定义的宏,对于编程经常会用到.下面这个表中就是一些常常用到的预定义宏. 宏(双下滑线) 意义 __DATE__ 进行预处理的日期(“Mmm dd yyyy”形式的字符串文字) __ ...

  5. C标准中一些预定义的宏,如__FILE__,__func__等

    C标准中一些预定义的宏 C标准中指定了一些预定义的宏,对于编程经常会用到.下面这个表中就是一些常常用到的预定义宏. 宏 意义 __DATE__ 进行预处理的日期(“Mmm dd yyyy”形式的字符串 ...

  6. .NET中那些所谓的新语法之三:系统预定义委托与Lambda表达式

    开篇:在上一篇中,我们了解了匿名类.匿名方法与扩展方法等所谓的新语法,这一篇我们继续征程,看看系统预定义委托(Action/Func/Predicate)和超爱的Lambda表达式.为了方便码农们,. ...

  7. 40 VSCode下.json文件的编写——(1) linux/g++ (2).json中参数与预定义变量的意义解释

    0 引言 转入linux/VSCode编程之后,迫切了解到有必有较为系统地学习一下VSCode中相关配置文件的写法.下面将分为 linux/g++编译指令..json文件关键词/替换变量的意义.编译链 ...

  8. PHP中的预定义超全局数组

    定义 超全局变量,是在全部作用域中始终可用的内置变量. PHP中的许多预定义变量都是"超全局的",这意味着它们在一个脚本的全部作用域中都可用. 在函数或方法中无需执行 global ...

  9. PHP中的预定义常量、类常量和魔术常量的区别

    PHP 向它运行的任何脚本提供了大量的预定义常量.不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了. 对于一些基本的常量是这些常量在 ...

随机推荐

  1. Java历程-初学篇 Day07 循环结构2 for循环

    一,格式 for(赋值语句//为循环变量赋初值;条件语句//循环结构的循环条件;赋值语句//迭代,修改循环变量的值){ //循环体; } 二,简单举例 for(int i=1;i<=10;i++ ...

  2. DotNetCore跨平台~一起聊聊Microsoft.Extensions.DependencyInjection

    写这篇文章的心情:激动 Microsoft.Extensions.DependencyInjection在github上同样是开源的,它在dotnetcore里被广泛的使用,比起之前的autofac, ...

  3. Centos7下安装php7

    通过编译的方式安装php7 1. 安装PHP7 ## 下载 wget http://us2.php.net/distributions/php-7.0.2.tar.gz ## 安装 tar zxvf ...

  4. 配合JdbcUtils最终版重写QueryRunner

    在使用QueryRunner类的时候,直接new本类,无需传递连接池或连接,如果是普通连接,最终释放连接 /** * * 在使用QueryRunner类的时候,直接new本类,无需传递连接池或连接 * ...

  5. Codeforces A. Trip For Meal

    A. Trip For Meal time limit per test 1 second memory limit per test 512 megabytes input standard inp ...

  6. CSS之 relative 特性

    1. 自身特性: 如left,right,top,bottom定位都是相对于自身位置定位. 当left与right同时存在,lfet生效. 当top与bottom同时存在,top生效. 无侵入,保留原 ...

  7. [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念

    上一篇:[Python] 文科生零基础学编程系列--对象.集合.属性.方法的基本定义 下一篇: (仍先以最简单的Excel的VBA为例,语法与Python不同,但概念和逻辑需要理解透彻) p.p1 { ...

  8. LINUX 笔记-iostat命令

    显示CPU和I/O统计信息 iostat的不带参数的显示CPU和I/ O的所有分区的统计信息 -c Display the CPU utilization report. -d Display the ...

  9. CentOS6编译LAMP基于FPM模式的应用wordpress

    CentOS6编译LAMP基于FPM模式的应用wordpress 引言:其实我们可以直接使用yum安装LAMP(Linux+Apache[httpd]+Mysql+PHP),比手动编译安装LAMP要简 ...

  10. 编译错误:expected an indented block

    python 对缩进要求非常严格,当运行时出现以下几种情况时,就需要修改缩进: 1.expected an indented block 直接缩进4个space空格或者一个tab.