特性的继承
using System.Runtime.InteropServices;
namespace System.Diagnostics
{
//
// 摘要:
// 指示调试器逐句通过代码,而不是单步执行代码。 无法继承此类。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
[ComVisible(true)]
public sealed class DebuggerStepThroughAttribute : Attribute
{
//
// 摘要:
// 初始化 System.Diagnostics.DebuggerStepThroughAttribute 类的新实例。
public DebuggerStepThroughAttribute();
}
}
示例如下:
using System;
using System.Diagnostics;
namespace AdvancedAttribute
{
class Program
{
static void Main(string[] args)
{
UseAttributeClass useAttributeClass = new UseAttributeClass();
useAttributeClass.DoMethod();
Console.ReadKey();
}
}
public class UseAttributeClass
{
//举例适应的特性[DebuggerStepThrough]
[DebuggerStepThrough]
public void DoMethod()
{
Console.WriteLine("这个方法很简单");
}
}
}
public class ResetPasswordViewModel
{
[Required]
[EmailAddress]
[Display(Name = "电子邮件")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "{0} 必须至少包含 {2} 个字符。", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "密码")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "确认密码")]
[Compare("Password", ErrorMessage = "密码和确认密码不匹配。")]
public string ConfirmPassword { get; set; }
public string Code { get; set; }
}
public class ForgotPasswordViewModel
{
[Required]
[EmailAddress]
[Display(Name = "电子邮件")]
public string Email { get; set; }
}
[Authorize]
public class AccountController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public AccountController()
{
}
}
类 Attribute 将预定义的系统信息或用户定义的自定义信息与目标元素相关联。 目标元素可以是程序集、类、构造函数、委托、枚举、事件、字段、接口、方法、可移植可执行文件模块、参数、属性、返回值、结构或其他属性。
属性提供的信息也称为元数据。 应用程序可以在运行时检查元数据,以控制程序处理数据的方式,或在运行时由外部工具控制应用程序本身的处理和维护方式之前。 例如,.NET 预定义并使用属性类型来控制运行时行为,某些编程语言使用属性类型来表示 .NET 通用类型系统不直接支持的语言功能。
所有属性类型都直接或间接派生自 Attribute 类。 属性可以应用于任何目标元素;多个属性可以应用于同一目标元素;和属性可由派生自目标元素的元素继承。 使用 AttributeTargets 类指定应用属性的目标元素。
一,系统自带特性 DebuggerStepThrough,Obsolete等等有一些是影响到了编译器的运行
二,自定义
特性看成类
using System;
namespace AdvancedAttribute1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("---------------------创建特性----------------------");
AttributeTest attributeTest = new AttributeTest();
attributeTest.Test();
Console.ReadKey();
}
}
#region 创建特性
class AttributeTest
{
public void Test()
{
Type type = typeof(UseAttribute);
object[] customAttributes = type.GetCustomAttributes(true);
foreach (object customAttribute in customAttributes)
{
DefindAttribute defindAttribute = customAttribute as DefindAttribute;
if (defindAttribute != null)
{
Console.WriteLine(defindAttribute.ShowInfo);
}
}
}
}
[Defind("这是第一个特性的创建!")]
class UseAttribute
{
}
class DefindAttribute : Attribute
{
public DefindAttribute(string showInfo)
{
ShowInfo = showInfo;
}
public string ShowInfo { get; set; }
}
#endregion
}
using AdvancedAttribute2.EnumExtend;
using System;
namespace AdvancedAttribute2
{
class Program
{
static void Main(string[] args)
{
//实验一
UserState userState = UserState.Frozen;
if (userState == UserState.Normal)
{
Console.WriteLine("正常");
}
else if (userState == UserState.Frozen)
{
Console.WriteLine("冻结");
}
else if (userState == UserState.Delete)
{
Console.WriteLine("删除");
}
//通过特性来操作
Console.WriteLine("--------------------通过特性来操作--------------------");
AttributeInvoke attributeInvoke = new AttributeInvoke();
Console.WriteLine(attributeInvoke.GetRemark(userState));
Console.ReadKey();
}
}
}
using System;
using System.Reflection;
namespace AdvancedAttribute2.EnumExtend
{
public class AttributeInvoke
{
public string GetRemark(UserState userState)
{
Type type = userState.GetType();
var fileId = type.GetField(userState.ToString());
//true 可以进行查找子类
if (fileId.IsDefined(typeof(RemarkAttribute), true))
{
RemarkAttribute remarkAttribute = (RemarkAttribute)fileId.GetCustomAttribute(typeof(RemarkAttribute), true);
return remarkAttribute.Remark;
}
else
{
return userState.ToString();
}
}
}
}
using System;
namespace AdvancedAttribute2.EnumExtend
{
///
/// 特性上面也可以添加特性
///
[AttributeUsage(AttributeTargets.Field,AllowMultiple =true)]//标记在字段上
public class RemarkAttribute : Attribute
{
///
/// 状态特性
///
///
public RemarkAttribute(string remark)
{
this.Remark = remark;
}
public string Remark { get; set; }//属性
}
}
namespace AdvancedAttribute2.EnumExtend
{
public enum UserState
{
///
/// 正常
///
[Remark("正常")]
Normal = 0,
///
/// 冻结
///
[Remark("冻结")]
Frozen = 1,
///
/// 删除
///
[Remark("删除")]
Delete = 2
}
}
第一步--定义特性
第二步--标记
第三步--调用
namespace AdvancedAttribute2.ShowExtend
{
[Show(ShowInfo = "我是在类上的特性")]
[Show(ShowInfo = "我是在类上的第二个特性")]
public class ShowTest
{
[Show(ShowInfo = "我是在方法上的特性")]
public void Test()
{ }
[Show(ShowInfo = "我是在属性上的特性---------")]
public string TestProperty { get; set; }//属性
[Show(ShowInfo = "我是在字段上的特性========")]
public string TestFiled;//字段
}
}
using System;
namespace AdvancedAttribute2.ShowExtend
{
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]//所有的地方都可以使用|多重标记
public class ShowAttribute : Attribute
{
public string ShowInfo { get; set; }
public void Show()
{
Console.WriteLine(ShowInfo);
}
}
}
普通写法
using System;
using System.Reflection;
namespace AdvancedAttribute2.ShowExtend
{
public class InvokeConter
{
public void InvokeManager<T>(T showTest) where T : new()
{
Type type = showTest.GetType();//获取类型
if (type.IsDefined(typeof(ShowAttribute), true))
{
//在类上面查找特性
object[] attributes = type.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributes)
{
attribute.Show();
}
//在方法上查找
foreach (MethodInfo method in type.GetMethods())
{
if (method.IsDefined(typeof(ShowAttribute), true))
{
object[] attributeMethodInfos = method.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributeMethodInfos)
{
attribute.Show();
}
}
}
//在属性上查找
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
if (propertyInfo.IsDefined(typeof(ShowAttribute), true))
{
object[] attributePropertyInfos = propertyInfo.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributePropertyInfos)
{
attribute.Show();
}
}
}
//在字段上查找
foreach (FieldInfo fieldInfo in type.GetFields())
{
if (fieldInfo.IsDefined(typeof(ShowAttribute), true))
{
object[] attributefieldInfos = fieldInfo.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributefieldInfos)
{
attribute.Show();
}
}
}
}
}
}
}
扩展写法
using System;
using System.Reflection;
namespace AdvancedAttribute2.ShowExtend
{
public static class InvokeConterKuoZhang
{
public static void InvokeManager<T>(this T showTest) where T : new()
{
Type type = showTest.GetType();//获取类型
if (type.IsDefined(typeof(ShowAttribute), true))
{
//在类上面查找特性
object[] attributes = type.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributes)
{
attribute.Show();
}
//在方法上查找
foreach (MethodInfo method in type.GetMethods())
{
if (method.IsDefined(typeof(ShowAttribute), true))
{
object[] attributeMethodInfos = method.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributeMethodInfos)
{
attribute.Show();
}
}
}
//在属性上查找
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
if (propertyInfo.IsDefined(typeof(ShowAttribute), true))
{
object[] attributePropertyInfos = propertyInfo.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributePropertyInfos)
{
attribute.Show();
}
}
}
//在字段上查找
foreach (FieldInfo fieldInfo in type.GetFields())
{
if (fieldInfo.IsDefined(typeof(ShowAttribute), true))
{
object[] attributefieldInfos = fieldInfo.GetCustomAttributes(typeof(ShowAttribute), true);
foreach (ShowAttribute attribute in attributefieldInfos)
{
attribute.Show();
}
}
}
}
}
}
}
Console.WriteLine("--------------------实验二普通方式--------------------");
ShowTest showTest = new ShowTest();
InvokeConter invokeConter = new InvokeConter();
invokeConter.InvokeManager(showTest);
Console.WriteLine("--------------------实验二扩展方法--------------------");
ShowTest showTest1 = new ShowTest();
showTest1.InvokeManager();
using System;
namespace AdvancedAttribute2.ValidateExtend
{
public abstract class AbstractValidateAttribute : Attribute
{
public abstract bool Validate(object Value);
}
}
using System;
namespace AdvancedAttribute2.ValidateExtend
{
public static class AttributeExtend
{
public static bool Validate<T>(this T t)
{
Type type = t.GetType();
//属性的验证
foreach (var property in type.GetProperties())
{
if (property.IsDefined(typeof(AbstractValidateAttribute), true))
{
object objValue = property.GetValue(t);
foreach (AbstractValidateAttribute attribute in property.GetCustomAttributes(typeof(AbstractValidateAttribute), true))
{
if (!attribute.Validate(objValue)) //如果成功了之后继续验证,否则直接返回
{
return false;
}
}
}
}
return true;
}
}
}
using System;
namespace AdvancedAttribute2.ValidateExtend
{
[AttributeUsage(AttributeTargets.Property)]
public class LongAttribute : AbstractValidateAttribute
{
private long _Long = 0;
public LongAttribute(long phoneLength)
{
this._Long = phoneLength;
}
public override bool Validate(object objValue)
{
return objValue != null && objValue.ToString().Length == 11;
}
}
}
using System;
namespace AdvancedAttribute2.ValidateExtend
{
[AttributeUsage(AttributeTargets.Property)]
public class RequiredAttribute : AbstractValidateAttribute
{
public override bool Validate(object objValue)
{
return objValue != null && !string.IsNullOrWhiteSpace(objValue.ToString());
}
}
}
using System;
namespace AdvancedAttribute2.ValidateExtend
{
[AttributeUsage(AttributeTargets.Property)]
public class StringLengthAttribute : AbstractValidateAttribute
{
private int _Mni = 0;
private int _Max = 0;
public StringLengthAttribute(int max, int min)
{
this._Max = max;
this._Mni = min;
}
public override bool Validate(object objValue)
{
return objValue != null && objValue.ToString().Length > this._Mni && objValue.ToString().Length < this._Max;
}
}
}
namespace AdvancedAttribute2.ValidateExtend
{
public class Student
{
public int Id { get; set; }
[Required]
[StringLength(10, 5)]
public string StudentName { get; set; }
[Required]
[Long(11)]
public long PhoneNumber { get; set; }
}
}
代码示例
https://github.com/KuKuDePerson/CSharpAdvancedAttribute