C#中的特性(Attribute)用途?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中的特性(Attribute)用途?相关的知识,希望对你有一定的参考价值。
你好:
1、问C#中的特性(Attribute)都有什么用途?
2、它可以用来验证某用户是否有操作某方法的权限吗?
我没有什么分,还请帮忙解答一下
如果可以用来验证某用户是否有操作某方法的权限,请给个例子好吗,谢谢啦
1、什么是Atrribute 首先,我们肯定Attribute是一个类,下面是msdn文档对它的描述: 公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。 在.NET中,Attribute被用来处理多种问题,比如序列化、程序的安全特征、防止即时编译器对程序代码进行优化从而代码容易调试等等。下面,我们先来看几个在.NET中标准的属性的使用,稍后我们再回过头来讨论Attribute这个类本身。(文中的代码使用C#编写,但同样适用所有基于.NET的所有语言)
2、Attribute作为编译器的指令 在C#中存在着一定数量的编译器指令,如:#define DEBUG, #undefine DEBUG, #if等。这些指令专属于C#,而且在数量上是固定的。而Attribute用作编译器指令则不受数量限制。比如下面的三个Attribute: Conditional:起条件编译的作用,只有满足条件,才允许编译器对它的代码进行编译。一般在程序调试的时候使用。 DllImport:用来标记非.NET的函数,表明该方法在一个外部的DLL中定义。 Obsolete:这个属性用来标记当前的方法已经被废弃,不再使用了。 参考技术A 1、就是可以在类、方法、属性等 增加一些额外信息,类似java的annotation。
2、可以。但是需要对方法进行拦截,在对方法调用之前,利用反射等方法可以取得这些额外信息,从而进行判断。追问
那么如何在调用方法之前,利用反射验证呢?
参考技术B 第一个问题,你可以参考我的另一个回答:http://zhidao.baidu.com/question/463506213.html。第二个问题,答案是可以。例子,我明天早上补充给你。追问
请问,如果方便可以把例子发给我看看吗,谢谢了 ^_^
追答给个Demo给你:
class Program
static void Main(string[] args)
Demo d=new Demo();
string userName="Lucy";
MethodInfo mi=d.GetType().GetMethod("Test");
if (mi == null) return;
AllowExecuteAttribute att=Attribute.GetCustomAttribute(mi, typeof(AllowExecuteAttribute)) as AllowExecuteAttribute;
if (att == null) return;
if (att.Check(userName))
Console.WriteLine("允许执行");
else
Console.WriteLine("不允许执行");
class Demo
[AllowExecute("Jack, Tom")]
public void Test()
///
/// 标识某方法允许执行的用户
///
[AttributeUsage(AttributeTargets.Method)]
public class AllowExecuteAttribute : Attribute
///
///
///
/// 允许执行的用户名的串联字符串
public AllowExecuteAttribute(string allowedUsers)
this._allowedUsers = allowedUsers;
private string _allowedUsers;
public bool Check(string userName)
return this._allowedUsers.ToLower().IndexOf(userName.ToLower()) > -1;
你说的这些我知道,主要是想知道第二个问题,能具体说说吗。如果是复制过来的就算了,那些讲的不清楚
[C#] 剖析 AssemblyInfo.cs - 从这里了解常用的特性 Attribute
剖析 AssemblyInfo.cs - 了解常用的特性 Attribute
【博主】反骨仔 【原文】http://www.cnblogs.com/liqingwen/p/5944391.html
序
之前,我们通过《C# 知识回顾 - 特性 Attribute》已经了解如何创建和使用特性 Attribute,这次,让我们一起来看看每次使用 VS 创建项目时所自带的文件 AssemblyInfo.cs。
目录
AssemblyInfo.cs
随机挑选一个 AssemblyInfo.cs 文件,展开图中的代码,看箭头↓
using System.Reflection; using System.Runtime.InteropServices; // 有关程序集的常规信息通过下列特性集 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 [assembly: AssemblyTitle("MusicStore")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Microsoft")] [assembly: AssemblyProduct("MusicStore")] [assembly: AssemblyCopyright("Copyright © Microsoft 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // 将 ComVisible 设置为 false 会使此程序集中的类型 // 对 COM 组件不可见。如果需要 // 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。 [assembly: ComVisible(false)] // 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID [assembly: Guid("a9ef3281-9049-4a52-a2f1-2061d442200e")] // 程序集的版本信息由下列四个值组成: // // 主版本 // 次版本 // 内部版本号 // 修订版本 // // 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值, // 方法是按如下所示使用 "*": [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
一、全局特性
大多数特性适用于特定的语言元素(如类或方法),但是,有种特性它们适用于整个程序集或模块,称为全局特性。如:AssemblyVersionAttribute 特性可用于向程序集中嵌入版本信息。
全局特性在源代码中出现在任何顶级 using
指令以及任何类型、模块或命名空间声明之前。全局特性可显示在多个源文件,但是,在单一编译传递必须编译文件。在 C# 项目中,它们在 AssemblyInfo.cs 文件中。
程序集特性是提供有关程序集的信息的值。它们分成以下类别:
①程序集标识特性
②信息性特性
③程序集清单特性
④强名称特性
1.程序集标识特性
三个特性 (使用强名称,如果适用) 确定程序集的标识:名称、版本和区域性。当在代码中引用时,这些特性构成程序集的完整名称需要。使用特性,可以将程序集的版本、区域性和名称值,由编译器,在 “程序集信息”对话框 的 Visual Studio IDE 设置,在创建程序集后,根据包含程序集清单的文件。AssemblyFlagsAttribute 特性指定程序集的多个副本是否可以共存。
图 - “程序集信息”对话框
图 - “程序集信息”对话框中的名词和 AssemblyInfo.cs 文件的对应关系
2.信息性特性
您可以使用信息性特性为程序集提供其他的公司或产品信息。
3.程序集清单特性
可以使用程序集清单特性提供程序集清单中的信息。其中包括标题、说明、默认别名和配置。
4.强名称特性(不深入)
一般存在 Visual Studio 的早期版本,若要使用强名称的程序集执行以下程序集级别特性:
虽然现在仍支持,但是,给程序集签名的首选方法是使用“签名页”。(这里不深入了解)
Obsolete
特性指示某个程序实体标记为建议不再使用的一个。 每次使用对实体标记为过时根据随后将生成警告或错误。1 /// <summary> 2 /// 旧类 3 /// </summary> 4 [Obsolete("请使用 " + nameof(NewClass))] 5 class OldClass 6 { 7 public void Method() { } 8 } 9 10 /// <summary> 11 /// 新类 12 /// </summary> 13 class NewClass 14 { 15 [Obsolete("请使用 " + nameof(NewMethod), true)] 16 public void OldMethod() { } 17 18 public void NewMethod() { } 19 }
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 var oldClass = new OldClass(); //警告 6 7 var newClass = new NewClass(); 8 newClass.OldMethod(); //报错 9 } 10 }
在此示例中应用 Obsolete
特性类 OldClass 和方法 NewClass.OldMethod
。此构造函数的第一个参数为警告或错误的信息,由于特性构造函数的第二个参数被应用于 NewClass.OldMethod
设置为 true
,此方法将导致编译器错误,而使用 OldClass 只将生成警告的类。
三、条件特性:Conditional
Conditional
特性执行方法依赖于预处理标识符。Conditional
属性是 ConditionalAttribute 的别名,可应用于方法或属性类。
在此示例中,Conditional
应用于方法以启用或禁用程序特定诊断信息示:
1 class Debug 2 { 3 [Conditional("DEBUG")] 4 public static void Output(string msg) 5 { 6 Console.WriteLine(msg); 7 } 8 } 9 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 Debug.Output("This is Debug!"); 15 Console.WriteLine("Done!"); 16 17 Console.Read(); 18 } 19 }
Conditional
特性通常用于在 DEBUG
标识符启用跟踪,并记录的功能的调试版本,但不在发布版本中。
将之前的代码简单改动下,使用 #if…#endif 包扎,结果和上图是一样的。
class Debug { public static void Output(string msg) { Console.WriteLine(msg); } } class Program { static void Main(string[] args) { #if DEBUG Debug.Output("This is Debug!"); #endif Console.WriteLine("Done!"); Console.Read(); } }
使用 Conditional
更加整洁,当然也可以将平常不太到用到或者容易出错的方法在 #if…#endif
内部块标明。
若要获取成员调用方信息,请使用适用于可选参数的属性。每个可选参数指定默认值。
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 CallerMethod(); 6 Console.Read(); 7 } 8 9 public static void CallerMethod() 10 { 11 TraceMessage("我是调用者"); 12 } 13 14 public static void TraceMessage(string msg, 15 [CallerMemberName] string name = "", 16 [CallerFilePath] string filePath = "", 17 [CallerLineNumber] int lineNumer = 0) 18 { 19 Trace.WriteLine($"{nameof(msg)}: {msg}"); 20 Trace.WriteLine($"{nameof(name)}: {name}"); 21 Trace.WriteLine($"{nameof(filePath)}: {filePath}"); 22 Trace.WriteLine($"{nameof(lineNumer)}: {lineNumer}"); 23 } 24 }
每次调用 CallerMethod 方法时,调用方信息将替换为可选参数的变量。
1.备注
你必须为每个可选参数指定显式默认值。不能将调用方信息特性应用于未指定为可选的参数。
调用方信息特性不会使参数成为可选参数。相反,它们会在忽略此参数时影响传入的默认值。
在编译时,调用方信息值将作为文本传入中间语言 (IL)。与异常的 StackTrace 特性的结果不同,这些结果不受模糊处理的影响。
你可显式提供可选参数来控制调用方信息或隐藏调用方信息。
传送门
《C# 知识回顾 - 表达式树 Expression Trees》
【参考】微软官方文档
以上是关于C#中的特性(Attribute)用途?的主要内容,如果未能解决你的问题,请参考以下文章