如何找做网站的客户,wordpress适合视频网站吗,建设网站的风险分析,跨境电商怎么发货到国外特性和反射
特性#xff08;Attribute#xff09;
特性#xff08;Attribute#xff09;是用于在运行时传递程序中各种元素#xff08;比如类、方法、结构、枚举、组件等#xff09;的行为信息的声明性标签。可以通过使用特性向程序添加声明性信息。一个声明性标签是通…特性和反射
特性Attribute
特性Attribute是用于在运行时传递程序中各种元素比如类、方法、结构、枚举、组件等的行为信息的声明性标签。可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号[ ]来描述的。
特性Attribute用于添加元数据如编译器指令和注释、描述、方法、类等其他信息。.Net 框架提供了两种类型的特性预定义特性和自定义特性。
Attribute是一种可由用户自有定义的修饰符Modifier可以用来修饰各种需要被修饰的目标。我们可以对类、以及C#程序集中的成员进行进一步的描述。
简单地说Attribute就是一种“附着物”——就像牡蛎吸附在船底或礁石上一样。 这些附着物的作用是为它们的附着体追加上一些额外的信息这些信息保存在附着物的体内——比如“这个类是我写的”或者“这个函数以前出过问题”等等
Attribute与注释的区别
注释是对程序源代码的一种说明主要目的是给人看的在程序被编译的时候会被编译器所丢弃因此它丝毫不会影响到程序的执行。
Attribute是程序代码的一部分它不但不会被编译器丢弃而且还会被编译器编译进程序集Assembly的元数据Metadata里。在程序运行的时候随时可以从元数据元数据.NET中元数据是指程序集中的命名空间、类、方法、属性等信息这些信息是可以通过Reflection读取出来的。中提取提取出这些附加信息并以之决策程序的运行。
规定特性Attribute
特性的目的是告诉编译器把程序结构的某组元数据嵌入程序集它可以放置在几乎所有的声明中但特定的属性可能限制在其上有效的声明类型。其语法为
在结构前放置特性片段来运用特性特性片段被方括号包围其中是特性名和特性的参数列表
例
// 不含参数的特性
[Serializable]
public class MyClass{...}// 带有参数的特性
[MyAttribute(firt,second,finally)]
public class MyClass {...}单个结构可以运用多个特性使用时可以把独立的特性片段互相叠在一起或使用分成单个特性片段特性之间用逗号分隔
// 独立的特性片段
[Serializable]
[MyAttribute(firt,second,finally)]
public class MyClass {...}// 逗号分隔
[MyAttribute(firt,second,finally), Serializable]
public class MyClass {...}某些属性对于给定实体可以指定多次。例如Conditional 就是一个可多次使用的属性
[Conditional(DEBUG), Conditional(TEST1)]
void TraceMethod()
{// ...
}预定义特性Attribute
.Net 框架提供了三种预定义特性
AttributeUsageConditionalObsolete
AttributeUsage
预定义特性 AttributeUsage 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。
规定该特性的语法如下
[AttributeUsage(validon,AllowMultipleallowmultiple,Inheritedinherited
)]其中
参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。参数 allowmultiple可选的为该特性的 AllowMultiple 属性property提供一个布尔值。如果为 true则该特性是多用的。默认值是 false单用的。参数 inherited可选的为该特性的 Inherited 属性property提供一个布尔值。如果为 true则该特性可被派生类继承。默认值是 false不被继承。
例如
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple true)]Conditional
这个预定义特性标记了一个条件方法其执行依赖于指定的预处理标识符。
它会引起方法调用的条件编译取决于指定的值比如 Debug 或 Trace。例如当调试代码时显示变量的值。
//#define CONDITINA
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;///Conditional
namespace _01_特性
{internal class Program{static void Main(string[] args){Test1();Test2();}[Conditional(CONDITINA)]public static void Test1(){Console.WriteLine(Test1);}public static void Test2(){Console.WriteLine(Test2);}}
}
Obsolete
这个预定义特性标记了不应被使用的程序实体。它可以让您通知编译器丢弃某个特定的目标元素。例如当一个新方法被用在一个类中但是您仍然想要保持类中的旧方法您可以通过显示一个应该使用新方法而不是旧方法的消息来把它标记为 obsolete过时的。
规定该特性的语法如下
[Obsolete(message
)]
[Obsolete(message,iserror
)]其中
参数 message是一个字符串描述项目为什么过时以及该替代使用什么。参数 iserror是一个布尔值。如果该值为 true编译器应把该项目的使用当作一个错误。默认值是 false编译器生成一个警告。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace _02_特性
{internal class Program{static void Main(string[] args){OldMethod();NewMethod();}[Obsolete(这个方法过时了,使用NewMethod来代替,true)]public static void OldMethod(){Console.WriteLine(旧方法);}public static void NewMethod(){Console.WriteLine(新方法);}}}
创建自定义特性Attribute
.Net 框架允许创建自定义特性用于存储声明性的信息且可在运行时被检索。该信息根据设计标准和应用程序需要可与任何目标元素相关。
创建并使用自定义特性包含四个步骤
声明自定义特性构建自定义特性在目标程序元素上应用自定义特性通过反射访问特性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace _03_自定义特性
{internal class Program{static void Main(string[] args){}}//1.声明自定义特性// [AttributeUsage(AttributeTargets.All, AllowMultipletrue, Inheritedtrue)];//2.构建自定义特性public class Something : Attribute {private string name;private string date;public string Name{get { return name; }set { name value; }}public string Date{get { return date; }set { date value; }}public Something(string name, string date){Name name;Date date;}}//3. 在目标程序元素上应用自定义特性[Something(吴亦凡,2024-03-27)]class Test{}}
反射(Reflection)
反射指程序可以访问、检测和修改它本身状态或行为的一种能力。
程序集包含模块而模块包含类型类型又包含成员。反射则提供了封装程序集、模块和类型的对象。
可以使用反射动态地创建类型的实例将类型绑定到现有对象或从现有对象中获取类型。然后可以调用类型的方法或访问其字段和属性。
优缺点
优点
反射提高了程序的灵活性和扩展性。降低耦合性提高自适应能力。它允许程序创建和控制任何类的对象无需提前硬编码目标类。
缺点
性能问题使用反射基本上是一种解释操作用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上普通程序不建议使用。使用反射会模糊程序内部逻辑程序员希望在源代码中看到程序的逻辑反射却绕过了源代码的技术因而会带来维护的问题反射代码比相应的直接代码更复杂。
反射Reflection的用途
反射Reflection有下列用途
它允许在运行时查看特性attribute信息。它允许审查集合中的各种类型以及实例化这些类型。它允许延迟绑定的方法和属性property。它允许在运行时创建新类型然后使用这些类型执行一些任务。
查看元数据
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace _04_反射
{internal class Program{static void Main(string[] args){//4.通过反射访问特性//Type获取有关加载的程序集中和其中定义的类型的信息,//typeof 用于获取类型的 System.Type 对象Type t typeof(Test);//获取自定义属性的var some t.GetCustomAttributes(typeof(Something), true);foreach (var s in some){Console.WriteLine(((Something)s).Name);Console.WriteLine(((Something)s).Date);}}}//1.声明自定义特性[AttributeUsage(AttributeTargets.All, AllowMultipletrue, Inheritedtrue)]//2.构建自定义特性public class Something : Attribute{private string name;private string date;public string Name{get { return name; }set { name value; }}public string Date{get { return date; }set { date value; }}public Something(string name, string date){Name name;Date date;}}//3. 在目标程序元素上应用自定义特性[Something(fanfan, 2024-03-27)][Something(xiangxiang, 2024-03-27)]class Test{}
}