clr via c# 定制特性
2021-01-10 17:31
标签:api line oci etc 利用 getc boolean 不可 类型 1,特性的应用范围:特性可应用于程序集,模块,类型,字段,方法,方法参数,方法返回值,属性,参数,泛型参数 2,利用前缀告诉编译器表明意图---下面的倾斜是必须的表明了我们的目标元素: 3,特性的本质是一个类型的实列,并且定制特性类必须从System.Attribute类派生 4,许多类:比如 StructLayoutAttribute MarshalAsAttribute DllImportAttribute InAttribute OutAttribute 都在命名空间System.Runtime.InteropServices命名空间中. 5,特性对象的构造,应为特性是类的实列,所以其支持类似 6,定制特性的简化写法, 7,定义自己的特性类 假设需要定义类FlagsAttribute 注意上面的AttributeUsage类 8,检测定制特性 使用IsDefined函数检测在类的实列中是否使用了特性!注意该方法在MemberInfo类中定义,注意,类Type派生自该类. 当使用GetMembers方法可以获取某个类的所有公开类型,注意,方法,属性,字段,构造器等都是Member之一. 然后利用分别对每一个成员获取其特性属性集合. 9,CustomAttributeExtensions中定义的三个方法 方法名称 与上述类似,用于获取某个对象(模块,程序集,type,memberinfo,parameterinfo,等)的特性的集合. 返回一个枚举集合. 10,反射命名空间 System.Reflection 提供了几个类允许检查模块的元数据 所有类都提供了IsDefined和GetCustomAttributes方法. 11,检测定制特性 注意----MemberInfo--->Type---->TypeInfo. 利用Type 可以获得 查看定制类的方法: 12,类的特性匹配 12.1新建一个枚举类型 Accounts 12.2新建一个账号等级特性 12.3创建一个测试函数 `12.4测试和结果 ClrFromCSharp_2_2.LearnAttribute.ChildAccount types can not write checks. 13,条件特性类----在特性类前面加入 特[Conditional("Test1"),Conditional("Test2")] 来控制,只有在当前文件下,定义了 #define Test1 或者 #define Test2 才能够生成特性实列. 也就是说,特性CondAttribute只有在由#define Test 或者#define VERIFY的情况下才有效 clr via c# 定制特性 标签:api line oci etc 利用 getc boolean 不可 类型 原文地址:https://www.cnblogs.com/frogkiller/p/12290340.html[assembly: AssemblyTitle("ClrFromCSharp_2_2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ClrFromCSharp_2_2")]
[assembly: AssemblyCopyright("Copyright ? 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(true)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("8c81c6c1-261e-445a-827d-fabe71033d57")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[DllImport("avifil32.dll"),CharSet=CharSet.Ansi)]//其中第一个为构造器参数,第二个为公共字段的值
private static extern void AVIFileInit();
[Serializable][Flags]
[Serializable,Flags]
[FlagsAttribute,SerializableAttribute]
[FlagsAttribute(),SerializableAttribute()]
[AttributeUsage(AttributeTargets.Enum,Inherited =false)]
public class FlagsAttribute : Attribute
{
public FlagsAttribute() { }
}
[AttributeUsage(AttributeTargets.All,Inherited =false)]
public class Flags1Attribute : Attribute
{
public Flags1Attribute() { }
}
// [Flags1]
public class TestAttribute
{
public TestAttribute()
{
if (this.GetType().IsDefined(typeof(Flags1Attribute), false))
Console.WriteLine("the object is Defined the Attribute Flags1");
else
Console.WriteLine("the object is not Defined the Attribute Flags1");
}
public static void Call()
{
TestAttribute a1 = new TestAttribute();
}
}
public static void Main()
{
try
{
// Get the type of MyClass1.
Type myType = typeof(MyClass1);
// Get the members associated with MyClass1.
MemberInfo[] myMembers = myType.GetMembers();
// Display the attributes for each of the members of MyClass1.
for(int i = 0; i true);
if(myAttributes.Length > 0)
{
Console.WriteLine("\nThe attributes for the member {0} are: \n", myMembers[i]);
for(int j = 0; j The type of the attribute is {0}.", myAttributes[j]);
}
}
}
catch(Exception e)
{
Console.WriteLine("An exception occurred: {0}", e.Message);
}
}
说明
IsDefined
public static bool IsDefined (this System.Reflection.MemberInfo element, Type attributeType, bool inherit);//inherit指定是否检查其上级,true则检查,false不检查
public static bool IsDefined (this System.Reflection.Assembly element, Type attributeType);
//检查某个程序集里面是否存在该特性
public static bool IsDefined (this System.Reflection.MemberInfo element, Type attributeType);
//检查某个类的成员是否包含特定的特性
public static bool IsDefined (this System.Reflection.Module element, Type attributeType);
//检查某个模块里面是否包含特定的特性
public static bool IsDefined (this System.Reflection.ParameterInfo element, Type attributeType);
//检查某个方法里面的参数是否包含特定的特性
GetCustomAttributes
GetCustomAttribute
public static Attribute GetCustomAttribute (this System.Reflection.Assembly element, Type attributeType);//从某个对象里面直接获取这个特性实列.
TypeInfo t = typeof(Calendar).GetTypeInfo();
IEnumerable
[Serializable]
[DefaultMember("Main")]
[DebuggerDisplay("Maoxiongbin",Name ="Mao",Target =typeof(CheckAttributeRef))]
public sealed class CheckAttributeRef//上面特性用于定义类的特性.
{
[Conditional("Debug")]
[Conditional("Release")]
public void DoSomething() { }//上面两个特性用于定义Dosomething方法
public CheckAttributeRef() { }//没有特性御用构造器
[CLSCompliant(true)]
[STAThread]
public static void Go()//2个特性用于静态方法GO()
{
ShowAttributes(typeof(CheckAttributeRef));//查看奔雷的特性情况
var members = from m in typeof(CheckAttributeRef).GetTypeInfo().DeclaredMembers.OfType
[Flags]
internal enum Accounts
{
Savings=0x0001,
Checking=0x0002,
Brokerage=0x0004
}
[AttributeUsage(AttributeTargets.Class)]//该特性只能在类上面
internal sealed class AccountsAttribute : Attribute//定义Accounts特性
{
private Accounts m_accounts;
public AccountsAttribute(Accounts accounts)//构造函数
{
m_accounts = accounts;
}
public override bool Match(object obj)//重写Match函数,定义匹配特性.
{
if (obj == null) return false;//如果obj是null则返回
if (this.GetType() != obj.GetType()) return false;//如果类型不匹配,则返回.
var other = obj as AccountsAttribute;
if ((other.m_accounts & m_accounts) != m_accounts)//判断other的m_accounts是否包含了this.m_accounts的信息.
return false;
return true;
}
public override bool Equals(object obj)//重写该函数,检查两个特性是否相等.
{
if (obj == null) return false;
if (this.GetType() != obj.GetType()) return false;
var other = obj as AccountsAttribute;
return other.m_accounts == m_accounts;
}
public override int GetHashCode()//重写了Equals,必须重写该函数.
{
return (int)m_accounts;
}
}
[Accounts(Accounts.Savings)]
internal sealed class ChildAccount { }//定义测试的类,并且定制特性对象Accounts,初始化为Accounts.Savings.
[Accounts((Accounts)7)]//定义测试的类,并且定制特性对象Accounts,初始化为Accounts.Savings|Checking|Brokerage
internal sealed class AdultAccount { }//(Accounts)7进行转换.
private static void CanWriteCheck(object obj)
{
Attribute checking = new AccountsAttribute(Accounts.Checking);//创建特性类对象
Attribute validAccounts = obj.GetType().GetCustomAttribute(typeof(AccountsAttribute));//从类中获取嵌入的特性类对象
if ((validAccounts != null) && (checking.Match(validAccounts)))//利用Match函数判断是否符合条件
Console.WriteLine("{0} types can write checks.", obj.GetType());
else
Console.WriteLine("{0} types can not write checks.", obj.GetType());
}
public static void GoAttributeMatch()
{
CanWriteCheck(new ChildAccount());//测试CHild类
CanWriteCheck(new AdultAccount());//测试Adult类
CanWriteCheck(new CheckAttributeRef());//测试CHeck类
}
//结果
ClrFromCSharp_2_2.LearnAttribute.AdultAccount types can write checks.//类的特性中由checking
ClrFromCSharp_2_2.LearnAttribute.CheckAttributeRef types can not write checks.//
//
//
[Conditional("TEST"),Conditional("VERIFY")]
[AttributeUsage(AttributeTargets.All)]
public sealed class CondAttribute : Attribute
{
}
public sealed class CondTest
{
public static void Go()
{
Console.WriteLine("CondAttribute is {0} applied to {1} type", (typeof(CondTest).IsDefined(typeof(CondAttribute),false)) ? "" : "not", typeof(CondTest).ToString());
}
}