Ò»°ãÔÚд·½·¨µÄʱºò£¬µÚÒ»²½¾ÍÊǽøÐвÎÊýÑéÖ¤£¬ÕâÒ²ÌåÏÖÁ˱àÂëÕßµÄϸÐĺÍçÇÃÜ£¬µ«ÊÇÔںܶàʱºòÕâ¸ö¹ý³ÌºÜ¿ÝÔïºÍ·¦Î¶£¬±ÈÈçÔÚÄõ½Ò»¸öAPIÉè¼ÆÎĵµµÄʱºò£¬Í¨³£»á¹æ¶¨ÀàÐͲÎÊýÊÇ·ñÔÊÐíΪ¿Õ£¬Èç¹ûÊÇ×Ö·û¿ÉÄÜÓ㤶ÈÏÞÖÆ£¬Èç¹ûÊÇÕûÊý¿ÉÄÜÐèÒªÅжϷ¶Î§£¬Èç¹ûÊÇÒ»Ð©ÌØÊâµÄÀàÐͱÈÈçµç»°ºÅÂ룬ÓʼþµØÖ·µÈ£¬¿ÉÄÜÐèҪʹÓÃÕýÔò±í´ïʽ½øÐÐÅжϡ£
ͨ³££¬ÎÒÃÇÒ»°ã¶¼ÊÇÔÚ·½·¨¿ªÊ¼µÄµØ·½½øÐÐÌõ¼þÅжϣ¬È»ºóÅ׳öºÏÊʵÄÒì³££¬ÕâÊÇ×îÆÕͨºÍͨÓõÄ×ö·¨£¬µ«ÊÇÔÚ.NETÖУ¬ÀûÓÃһЩÓïÑÔÌØÐÔºÍÀà¿â£¬¿ÉÒÔʹÓÃһЩÆäËûµÄ·½Ê½½«ÎÒÃÇ´Ó¸´ÔÓ·±ËöµÄ¹¤×÷Öнâ·Å³öÀ´¡£±¾ÎÄÖðÒ»½éÉÜÄܹ»ÓÃÀ´½øÐвÎÊýÑéÖ¤µÄ·½Ê½£¬ËûÃǰüÀ¨Ö±½ÓÅжÏÓï¾ä£¬°ïÖúÀ࣬À©Õ¹·½·¨£¬Customer
Attribute£¬Enterprise Liberary£¬Debug.Assert£¬Code ContractµÈ¡£¿ÉÒÔ¿´µ½ÔÚ.NETÖÐËæ×Ű汾µÄÑÝ»¯£¬Öð²½Ìí¼ÓÁ˺ܶàÉùÃ÷ʽ±à³Ì(Declarative
programming)µÄ·ç¸ñ£¬ÕâÑùµÄ´úÂë»áÖ±½Ó±íÃ÷what¶ø²»ÊÇhow£¬´Ó¶øÊ¹µÃ´úÂë¸ü¼ÓÇåÎúºÍÒ×ά»¤¡£
ÏÖÔÚÀ´¿´ÏÂÕâЩ²ÎÊýÑéÖ¤µÄ·½·¨¡£
Ò» Ò»°ãµÄ·½·¨
¼ÙÉèÎÒÃÇÓÐÒ»¸ö·½·¨ÈçÏ£¬ÓÃÀ´½øÐеǼÇ×¢²á£¬ÐèÒª´«ÈëÐÕÃûºÍÄêÁä¡£
public bool Register(string name, int age) { //insert into db } |
µ±È»£¬²»ÊÇ´«½øÊ²Ã´¶«Î÷¶¼Äܵ÷ÓÃÎÒÃǵķ½·¨¡£Ò»°ãµØ£¬ÎÒÃÇÊ×ÏÈÒª×öµÄÊÇ£¬¶Ô²ÎÊý½øÐкϷ¨ÐÔÑéÖ¤£¬±ÈÈçÈç¹ûÒª²Î¼ÓÉϺ£¹ú¼ÊÂíÀËɱÈÈü£¬ÐèÒªÄêÁä´óÓÚ10ËêСÓÚ70Ëê¡£Ò»°ãµÄÑéÖ¤·½·¨ÈçÏ£º
public bool Register(string name, int age) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("name should not be empty", "name"); } if (age < 10 || age > 70) { throw new ArgumentException("the age must between 10 and 70","age"); } //insert into db } |
ÎÒÃǻᷢÏÖ£¬Èç¹ûÿһ¸ö·½·¨¶¼ÕâÑùÅжϵϰ£¬·Ç³£Âé·³ºÍ·±Ëö¡£ÓÚÊǾÍÏëµ½°ÑËûÌáÈ¡µ½Ò»¸ö°ïÖú·½·¨ÖС£
public static class ArgumentHelper { public static void RequireRange(int value, int minValue, int maxValue, string argumentName) { if (value > maxValue || value < minValue) { throw new ArgumentException(string.Format("The value must be between {0} and {1}", minValue, maxValue), argumentName); } }
public static void RequireNotNullOrEmpty(string
value, string argumentName)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("The value can't
be null or empty", argumentName);
}
}
} |
ÕâÑù£¬ÔÚËùÓÐÐèÒª½øÐÐÇø¼äÑéÖ¤ºÍ·Ç¿ÕÑéÖ¤µÄµØ·½£¬µ÷ÓÃÕâ¸ö°ïÖúÀàÖеķ½·¨¼´¿É¡£
public bool Register(string name, int age) { ArgumentHelper.RequireNotNullOrEmpty(name,"name"); ArgumentHelper.RequireRange(age,10,70,"age"); //insert into db } |
ÔÚC#3.0 ÖУ¬ÒýÈëÁËÀ©Õ¹·½·¨£¬Òò´Ë¿ÉÒÔÒÔÒ»ÖÖ¸üÓÅÑŵķ½Ê½À´½øÐвÎÊýÑéÖ¤£¬ÎÒÃǽ«Ç°ÃæµÄ°ïÖú·½·¨¸ÄдÈçÏÂ:
public static class ArgumentHelper { public static void RequireRange(this int value, int minValue, int maxValue, string argumentName) { if (value > maxValue || value < minValue) { throw new ArgumentException(string.Format("The value must be between {0} and {1}", minValue, maxValue), argumentName); } }
public static void RequireNotNullOrEmpty(this
string value, string argumentName)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("The value can't
be null or empty", argumentName);
}
}
} |
ÕâÑù£¬ÎÒÃǵÄÑéÖ¤±ä³ÉÁËÈçÏ£º
public bool Register(string name, int age) { name.RequireNotNullOrEmpty("name"); age.RequireRange(10,70,"age"); //insert into db } |
ÓÐÁËÀ©Õ¹·½·¨£¬¾Í¿ÉÒÔд³öºÜ¶àÀàËÆLINQµÄ±È½ÏÁ÷³©µÄÑéÖ¤Óï¾äÀ´¡£Ò»Ð©ÀàËÆµÄÑéÖ¤Àà¿âÒ²ÌṩÁËÀàËÆ¹¦ÄÜ¡£ÈçFluentValidation£¬CuttingEdge.ConditionsµÈ¡£±ÈÈçÕâÀïÈ¡×ÔCuttingEdge.Condition
ÀïÃæµÄÀý×Ó¡£
public ICollection GetData(Nullable<int> id, string xml, IEnumerable<int> col) { // Check all preconditions: Condition.Requires(id, "id") .IsNotNull() // throws ArgumentNullException on failure .IsInRange(1, 999) // ArgumentOutOfRangeException on failure .IsNotEqualTo(128); // throws ArgumentException on failure
Condition.Requires(xml, "xml")
.StartsWith("<data>") // throws
ArgumentException on failure
.EndsWith("</data>") // throws
ArgumentException on failure
.Evaluate(xml.Contains("abc") || xml.Contains("cba"));
// arg ex
Condition.Requires(col, "col")
.IsNotNull() // throws ArgumentNullException on
failure
.IsEmpty() // throws ArgumentException on failure
.Evaluate(c => c.Contains(id.Value) || c.Contains(0));
// arg ex
// Do some work
// Example: Call a method that should not return
null
object result = BuildResults(xml, col);
// Check all postconditions:
Condition.Ensures(result, "result")
.IsOfType(typeof(ICollection)); // throws PostconditionException
on failure
return (ICollection)result;
} |
ÀûÓÃÀ©Õ¹·½·¨Ò²¿ÉÒÔд³öÈçÏÂͼÖÐÕâÖֱȽϸãЦµÄÓï¾ä¡£

¶þ ʹÓÃÀà¿â»òÕß¿ò¼Ü
³ýÁË×Ô¼ºÐ´·½·¨Ö®Í⣬һЩÀà¿âºÍ¿ò¼ÜÒ²ÌṩÁ˲ÎÊýÑéÖ¤µÄÄ£¿é¡£
΢ÈíÆóÒµ¿â£¨Enterprise Liberary£©ÖÐÌṩÁËÒ»¸öÃûΪValidation Application
BlockµÄ×é¼þ£¬×¨ÃÅÓÃÀ´ÑéÖ¤¡£°²×°Ö®ºó£¬ÔËÐÐEntLibConfig.exe ¾Í¿ÉÒÔʹÓýçÃæµÄ·½Ê½À´Ìí¼ÓÑéÖ¤
»¹ÊÇÒÔÇ°ÃæµÄ´úÂëΪÀý×Ó¡£ÎÒÃǽ«nameºÍage·âװΪһ¸öÃûΪPersonµÄÀàµÄ×ֶΣ¬È»ºóʹÓÃÆóÒµ¿âÀ´½øÐÐÑéÖ¤¡£ÔÊÐíEntLibConfig.exe£¬¼ÓÔØÎÒÃDZàÒëºÃµÄdll»òÕßexe£¬È»ºóÑ¡ÔñÐèÒªÑéÖ¤µÄ×ֶλòÕß·½·¨£¬È»ºóÌí¼ÓºÏÊʵÄÑéÖ¤¹æÔò£¬ÈçÏÂͼ£º

Íê³ÉÖ®ºó£¬±£´æÎªapp.configÎļþ£¬¸ÃÎļþÄÚÈÝÈçÏ£º
<configuration> <configSections> <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings,
Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" requirePermission="true" /> </configSections> <validation> <type name="ValidationConsole.Program+Person" defaultRuleset="Validation Ruleset" assemblyName="ValidationConsole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> <ruleset name="Validation Ruleset"> <properties> <property name="Name"> <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator,
Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" messageTemplate="ÐÕÃû²»ÄÜΪ¿Õ" name="Not Null Validator" /> </property> <property name="Age"> <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.RangeValidator,
Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" culture="zh-CN" lowerBound="10" lowerBoundType="Exclusive" upperBound="70" messageTemplate="Age should between
10 and 70
" name="Range Validator" /> </property> </properties> </ruleset> </type> </validation> </configuration>
|
¿ÉÒÔ¿´µ½ÆóÒµ¿âʵ¼ÊÉÏÊÇÉú³ÉÒ»¸öapp.configÎļþ£¬È»ºóÔÚÎļþÖÐдÈëÁ˲ÎÊýµÄÑéÖ¤Ìõ¼þ£¬È»ºóÔÚÔËÐеÄʱºòÒýÓÃÆóÒµ¿âµÄÏà¹Ødll½øÐÐÑéÖ¤¡£²ÎÊýÑéÖ¤ÊÇ¿ÉÒÔÅäÖõ쬾ßÌåµÄʹÓ÷½·¨ÈçÏ£º
public class Person { public string Name { get; set; } public int Age { get; set; }
public Person(string name, int age)
{
this.Name = name;
this.Age = age;
}
}
static void Main(string[] args)
{
Validator<Person> customerValidator = ValidationFactory.CreateValidator<Person>("Validation
Ruleset");
Person myCustomer = new Person("admin",9);
ValidationResults validateResult = customerValidator.Validate(myCustomer);
if (!validateResult.IsValid)
{
for (int i = 0; i < validateResult.Count; i++)
{
Console.WriteLine("ÑéÖ¤³ö´í {0}:" + validateResult.ElementAt(i).Message,
i + 1);
}
}
else
{
Console.WriteLine("ÕýÈ·");
}
Console.ReadKey();
} |
ÔËÐнá¹ûÈçÏ£º

ASP.NET MVC
»¹¿ÉÒÔÀûÓÃ×Ô¶¨ÒåÊôÐÔ(Customer Attribute)À´½øÐвÎÊýÑéÖ¤£¬ASP.NET MVC µÄModelÖоÍÊÇʹÓÃÊý¾Ý±ê¼Ç(Data
Annotations)ÕâÖÖÊôÐÔÀ´½øÐÐÑéÖ¤¡£Data AnnotationsÆäʵÊÇһϵÁм̳Ð×ÔAttributeµÄ¿ÉÒÔÓÃÔÚÀà»òÕßÀàµÄÊôÐÔÉϵÄ×Ô¶¨ÒåÊôÐÔÀà¡£
System.ComponentModel.DataAnnotations
³ÌÐò¼¯ÖÐÄÚ½¨ÓÐһЩÖîÈç Required, Range, RegularExpression and StringLengthµÄÀ࣬
ÕâЩ×Ô¶¨ÒåÊôÐÔÀà¶¼¼Ì³Ð×ÔValidationAttribute³éÏóÀࣺ
public abstract class ValidationAttribute : Attribute { public string ErrorMessage { get; set; }
public virtual bool IsValid(object value);
protected virtual ValidationResult IsValid(object
value, ValidationContext
validationContext);
// other members
} |
Èç¹ûÔÚASP.NET MVC ÖУ¬ÎÒÃǵÄPerson Model¾Í¿ÉÒÔд³ÉÈçÏ£º
public class Person { [Required] public string Name { get; set; } [Range(10, 70)] public int Age { get; set; } } |
ºÜ¼ò½à£¬ÔÚ±àдʵÌåÀàµÄʱºò£¬¾Í¿ÉÒÔ˳±ã°ÑÑéÖ¤¹æÔò¸ø¶¨ÁË¡£ÕâÑù£¬ÎÒÃÇÔÚʵÀý»¯PersonÀ࣬Ȼºóµ÷Óÿò¼ÜÖÐÏàÓ¦µÄ·½·¨£¬Èç¹û²»Âú×ãÌõ¼þ£¬¾Í»áÅ׳öÏàÓ¦µÄÒì³£¡£
PostSharp
һЩÉÌÒµÈí¼þ£¬¸üÊǽ«ÀûÓÃÊôÐÔ½øÐÐÑéÖ¤×öµ½Á˼«Ö£¬±ÈÈçPostSharpÕâ¿îÉÌÒµÈí¼þ¡£ÏÂÃæÊǸÃÍøÕ¾µÄÐû´«Ò³£º

¿ÉÒÔ¿´µ½£¬ÔÚ·½·¨µÄ²ÎÊýÖУ¬¿ÉÒÔÔÚÇ°ÃæÊ¹ÓÃ×Ô¶¨ÒåÊôÐÔÀ´±ê¼Ç£¬È»ºóÔÚϵͳÔËÐеÄʱºò½øÐж¯Ì¬µÄÑéÖ¤¡£
PostSharpʹÓõÄÊÇÒ»ÖÖËùν¾²Ì¬×¢ÈëµÄ·½Ê½£¬Ò²¾ÍÊÇÔÚ±àÒëºÃµÄ³ÌÐò¼¯ÖеÄÀàÐÍ»òÕßij¸ö·½·¨Àï×¢ÈëIL´úÂ룬ÊÇÔÚ´úÂë±àÒëµÄʱºò£¬¶ø²»ÊÇÔÚÔËÐÐʱעÈëµÄ¡£Visual
Studioͨ¹ýMSBuildÀ´Ö´ÐÐÉú³É¹ý³Ì£¬PostSharpÊǰÑ×Ô¼º×÷ΪһϵÁеÄBuild TaskÀ´²åÈëµ½´úÂëÉú³É¹ý³ÌÖÐÀ´µÄ¡£ÆäÔÀí¿ÉÒԲο´
.NETϵÄAOP£º PostSharp ÔÀí·ÖÎö ÕâÆªÎÄÕ¡£ÕâÀïÒýÓÃÁËÎÄÖеÄÒ»·ùͼ£¬ºÜÐÎÏóµÄ˵Ã÷ÁËPostSharpµÄÔÀí£º

×Ô¼º¶¯ÊÖ
ÆäʵʹÓÃÊôÐÔÀ´½øÐÐÑéÖ¤ºÜ¼òµ¥£¬ÎÒÃÇÒ²¿ÉÒÔ×Ô¼º¶¯ÊÖÀ´ÊµÏÖÀàËÆPostSharpµÄ¹¦ÄÜ£¬µ±È»£¬ÔÚʹÓÃCustomer
Attribute֮ǰ£¬Ê×ÏÈÄúÐèÒªÁ˽âAttributeÕâ¸öÀ࣬ ÖÐÎĵϰ£¬Äú¿ÉÒԲο¼CSDNÉϵÄAttributeÔÚ.net±à³ÌÖеÄÓ¦ÓÃÕâһЩÁÐ6ƪÎÄÕ¡£ÏÂÃæ¾Í½éÉÜÈçºÎʵÏÖPostSharpÖеÄʹÓÃ×Ô¶¨ÒåÊôÐÔ¶Ô²ÎÊý½øÐбê¼ÇÑéÖ¤¡£ÆäʵÄú¿´¹ýASP.NET
MVC ÖеÄSystem.ComponentModel.DataAnnotationsÓ¦¸Ã¾Í¿ÉÒÔÖªµÀ¸ÃÔõôʵÏÖÁË¡£
Ê×ÏÈ£¬Ð½¨Ò»¸öArgumentValidationAttribute³éÏóÀà¡£ÒòΪ°´ÕÕÔ¼¶¨£¬ËùÓм̳Ð×ÔAttributeµÄÀàÃû³ÆºóÃæ±ØÐë´øÓÐAttribute¡£Õâ¸öÀàÖÐÖ»ÓÐÒ»¸ö³éÏó·½·¨Validate£¬ÓÃÀ´ÑéÖ¤¡£
public abstract class ArgumentValidationAttribute:Attribute { public abstract void Validate(object value, string argumentName); } |
È»ºó£¬ÎÒÃǶ¨ÒåÒ»¸öÓÃÀ´ÑéÖ¤·Ç¿ÕµÄ×Ô¶¨ÒåÊôÐÔNotNullAttribute£¬×¢Òâµ½ÔÚ¸ÃÀàÉÏ£¬ÎÒÃÇʹÓÃÁËAttributeUsageÊôÐÔ£¬ÔÚÆä¹¹Ô캯Êý²ÎÊýÖУ¬ÎÒÃÇ´«ÈëÁË
AttributeTargets.Parameter Õâ¸öö¾Ù£¬±íÃ÷¸Ã±ê¼ÇÖ»ÄÜÓÃÔÚ·½·¨µÄ²ÎÊýÉÏ¡£
[AttributeUsage(AttributeTargets.Parameter)] public class NotNullAttribute : ArgumentValidationAttribute { public override void Validate(object value, string argumentName) { if (value == null) throw new ArgumentNullException(argumentName); } } |
È»ºó¶¨ÒåÁËÒ»¸öÓÃÀ´ÑéÖ¤·¶Î§µÄInRangeAttribute£¬ÕâÀïÎÒÃǶ¨ÒåÁËÒ»¸ö¹¹Ô캯Êý£¬Ê¹µÃ¿ÉÒÔ´«ÈëÒ»¸öÇø¼ä·¶Î§¡£
[AttributeUsage(AttributeTargets.Parameter)] public class InRangeAttribute : ArgumentValidationAttribute { private int min; private int max;
public InRangeAttribute(int min, int max)
{
this.min = min;
this.max = max;
}
public override void Validate(object value,
string argumentName)
{
int intValue = (int)value;
if (intValue < min || intValue > max)
{
throw new ArgumentOutOfRangeException(argumentName,string.Format("min={0},max={1}",min,max));
}
}
} |
ÓÐÁËÉÏÃæÁ½¸öÀ࣬ÎÒÃÇ»¹ÐèÒªÔÚÒ»¸ö´óµÄ¿ò¼ÜÀàÑéÖ¤µ÷ÓÃÕâЩÑéÖ¤·½·¨£¬Í¨³££¬ÎÒÃÇ»áʹÓÃÖîÈç½Ó¿Ú×¢ÈëµÄ·½Ê½À´ÊµÏÖ¡£ÕâÀï½öÁгö¹Ø¼ü²¿·Ö¡£
public class ValidationInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { ParameterInfo[] parameters = invocation.Method.GetParameters(); for (int index = 0; index < parameters.Length; index++) { var paramInfo = parameters[index]; var attributes = paramInfo.GetCustomAttributes(typeof(ArgumentValidationAttribute), false);
if (attributes.Length == 0)
continue;
foreach (ArgumentValidationAttribute attr in
attributes)
{
attr.Validate(invocation.Arguments[index], paramInfo.Name);
}
}
invocation.Proceed();
}
} |
È»ºó£¬ÔÙ»ØÍ·¿´ÎÒÃǵĴúÂ룬ÎÒÃÇÊ×ÏȳéÏóÒ»¸öIRegister½Ó¿Ú£º
public interface IRegister { void Register([NotNull] string name, [InRange(10, 70)] int age); } |
¿ÉÒÔ¿´µ½£¬ÏÖÔÚ½Ó¿ÚÖеķ½·¨£¬²ÎÊýÇ°ÃæÒѾ¿ÉÒÔдÎÒÃÇ֮ǰ¶¨ÒåµÄÓÃÓÚÑéÖ¤¹¦ÄܵÄÊôÐÔÁË£¬½Ó¿Ú·½·¨Öж¨ÒåÁ˲ÎÊýµÄÑéÖ¤¹æÔòÖ®ºó£¬ËùÓÐʵÏָýӿڵķ½·¨ÖоͲ»ÐèÒªÔٴζ¨ÒåÁË¡£ÎÒÃǵÄ×¢²áÀàÖ»ÐèҪʵÏָýӿڣ¬È»ºóÔÙÖ´ÐÐRegister֮ǰ£¬Í³Ò»ÑéÖ¤¼´¿É¡£
public class ShMarathon : IRegister {
public void Register(string name, int age)
{
//doesn't need to validate
//insert into db
}
} |
ÕâÖÖ·½Ê½ÆäʵÊÇAOP(ÃæÏò·½Ãæ±à³Ì)µÄÒ»ÖÖ˼Ï룬¸ü¶àµÄ×ÊÁÏÄú¿ÉÒԲο¼AOP in .NET: Practical
Aspect-Oriented ProgrammingºÍDependency Injection in
.NET
Èý Code Contract
Code Contracts ÊÇ΢ÈíÑо¿Ôº¿ª·¢µÄÒ»¸ö±à³ÌÀà¿â£¬ÎÒ×îÔç¿´µ½ÊÇÔÚC#
In Depth µÄµÚ¶þ°æÖУ¬µ±Ê±.NET 4.0»¹Ã»ÓгöÀ´£¬µ±Ê±ÊÇ×÷Ϊһ¸öµÚÈý·½Àà¿â´æÔڵ쬵½ÁË.NET
4.0Ö®ºó£¬ÒѾ¼ÓÈëµ½ÁË.NET BCLÖУ¬¸ÃÀà´æÔÚÓÚSystem.Diagnostics.Contracts
Õâ¸öÃüÃû¿Õ¼äÖС£
namespace System.Diagnostics.Contracts { // Summary: // Contains static methods for representing program contracts such as preconditions, // postconditions, and object invariants. public static class Contract { public static event EventHandler<ContractFailedEventArgs> ContractFailed; public static void Assert(bool condition); public static void Assert(bool condition, string userMessage); public static void Assume(bool condition); public static void Assume(bool condition, string userMessage); public static void EndContractBlock(); public static void Ensures(bool condition); public static void Ensures(bool condition, string userMessage); public static void EnsuresOnThrow<TException>(bool condition) where TException : Exception; public static void EnsuresOnThrow<TException>(bool condition, string userMessage) where TException : Exception; public static bool Exists<T>(IEnumerable<T> collection, Predicate<T> predicate); public static bool Exists(int fromInclusive, int toExclusive, Predicate<int> predicate); public static bool ForAll<T>(IEnumerable<T> collection, Predicate<T> predicate); public static bool ForAll(int fromInclusive, int toExclusive, Predicate<int> predicate); public static void Invariant(bool condition); public static void Invariant(bool condition, string userMessage); public static T OldValue<T>(T value); public static void Requires<TException>(bool condition) where TException : Exception; public static void Requires(bool condition); public static void Requires(bool condition, string userMessage); public static void Requires<TException>(bool condition, string userMessage) where TException : Exception; public static T Result<T>(); public static T ValueAtReturn<T>(out T value); } } |
Code Contract ʹµÃ.NET ÖÐÆõԼʽÉè¼ÆºÍ±à³Ì±äµÃ¸ü¼ÓÈÝÒ×£¬ContractÖеÄÕâЩ¾²Ì¬·½·¨·½·¨°üÀ¨
1.Requires£ºº¯ÊýÈë¿Ú´¦±ØÐëÂú×ãµÄÌõ¼þ
2.Ensures£ºº¯Êý³ö¿Ú´¦±ØÐëÂú×ãµÄÌõ¼þ
3.Invariants£ºËùÓгÉÔ±º¯Êý³ö¿Ú´¦¶¼±ØÐëÂú×ãµÄÌõ¼þ
4.Assertions£ºÔÚijһµã±ØÐëÂú×ãµÄÌõ¼þ
5.Assumptions£ºÔÚijһµã±ØÈ»Âú×ãµÄÌõ¼þ£¬ÓÃÀ´¼õÉÙ²»±ØÒªµÄ¾¯¸æÐÅÏ¢
Code Contract µÄʹÓÃÎĵµÄú¿ÉÒÔ´Ó¹ÙÍøÏÂÔØµ½¡£ÎªÁË·½±ãʹÓÃVisual Studio¿ª·¢¡£ÎÒÃÇ¿ÉÒÔ°²×°Ò»¸öCode
Contracts Editor Extensions²å¼þ¡£°²×°ÍêÁËÖ®ºó£¬µã»÷Visual StudioÖеÄÏîÄ¿ÊôÐÔ£¬¿ÉÒÔ¿´µ½ÈçÏ·ḻµÄÑ¡ÔñÏ

ÏÖÔÚ£¬ÔÚÎÒÃǵÄRegister·½·¨ÖУ¬¿ÉÒÔʹÓÃContractÀ´½øÐÐÅжϣ¬Ê¹Ó÷½Ê½ºÍDebug.AssertÀàËÆ£º
public static bool Register(string name, int age) { Contract.Requires(!String.IsNullOrEmpty(name)); Contract.Requires(age > 10 && age < 70); //insert into db return false; } |
µ±ÎÒÃÇ´«Èë´íÎóµÄageÖµµÄʱºò£¬¾Í»á±¨´í£º

ContractºÍDebug.AssertÓÐЩµØ·½ÏàËÆ£º
1.¶¼ÌṩÁËÔËÐÐʱ֧³Ö£ºÕâЩContracts¶¼ÊÇ¿ÉÒÔ±»ÔËÐе쬲¢ÇÒÒ»µ©Ìõ¼þ²»±»Âú×㣬»áµ¯³öÀàËÆAssertµÄÒ»ÑùµÄ¶Ô»°¿ò±¨´í£¬ÈçÏ£º
2.¶¼¿ÉÒÔÔÚËæÒâµÄÔÚ´úÂëÖйرմò¿ª¡£
µ«ÊÇContractÓиü¶àºÍ¸üÇ¿´óµÄ¹¦ÄÜ£º
1.ContractsµÄÒâͼ¸ü¼ÓÇåÎú£¬Í¨¹ý²»Í¬µÄRequires/EnsuresµÈµÈµ÷Ó㬴ú±í²»Í¬ÀàÐ͵ÄÌõ¼þ£¬±Èµ¥´¿µÄAssert¸üÈÝÒ×Àí½âºÍ½øÐÐ×Ô¶¯·ÖÎö
2.ContractsµÄλÖøü¼Óͳһ£¬½«3ÖÖ²»Í¬Ìõ¼þ¶¼·ÅÔÚ´úÂëµÄ¿ªÊ¼´¦£¬¶ø·ÇÉ¢¼ûÔÚº¯ÊýµÄ¿ªÍ·ºÍ½á⣬±ãÓÚ²éÕҺͷÖÎö¡£
3.²»Í¬µÄ¿ª·¢ÈËÔ±¡¢²»Í¬µÄС×é¡¢²»Í¬µÄ¹«Ë¾¡¢²»Í¬µÄ¿â¿ÉÄܶ¼»áÓÐ×Ô¼ºµÄAssert£¬Õâ¾Í´ó´óÔö¼ÓÁË×Ô¶¯·ÖÎöµÄÄѶȣ¬Ò²²»ÀûÓÚ¿ª·¢ÈËÔ±±àд´úÂë¡£¶øContractsÖ±½Ó±».NET
4.0Ö§³Ö£¬ÊÇͳһµÄ¡£
4.ËüÌṩÁ˾²Ì¬·ÖÎöÖ§³Ö£¬Õâ¸öÎÒÃÇ¿ÉÒÔͨ¹ýÅäÖÃÃæ°å¿´µ½£¬Í¨¹ý¾²Ì¬·ÖÎöContracts£¬¾²Ì¬·ÖÎö¹¤¾ß¿ÉÒԱȽÏÈÝÒ×ÕÆÎÕº¯ÊýµÄ¸÷ÖÖÓйØÐÅÏ¢£¬ÉõÖÁ¿ÉÒÔ×÷ΪIntellisense
ContractÖаüº¬ÁËÈý¸ö¹¤¾ß:
ccrewrite, ͨ¹ýÏò³ÌÐò¼¯ÖÐЩÈç¶þ½øÖÆÊý¾Ý£¬À´Ö§³ÖÔËÐÐʱ¼ì²â
cccheck, ÔËÐÐʱ¼ì²â
ccdoc, ½«Contract×Ô¶¯Éú³ÉXMLÎĵµ
ÏÂͼÊÇContractµÄÔÀí£¬Í¼Æ¬À´×Ô .NET 4.0ÖеÄй¦ÄܽéÉÜ£ºÆõԼʽÉè¼Æ
(Design By Contracts) ÕâÆªÎÄÕ£¬ ÕâÒ²ÊÇΪʲôҪ±ÈDebug.AssertÇ¿´óµÄÔÒò£¬ÎÒÃÇÖ»ÐèÒª½«ËùÓеÄÖ´ÐÐǰÅжϺÍÖ´ÐкóÅжϵÄÌõ¼þ£¬Ð´µ½Ò»¸öµØ·½£¬È»ºóÔÙ±àÒë´úÂëµÄʱºò£¬ccrewrite
»á°ïÎÒÃÇÉú³ÉÏàÓ¦µÄ´úÂ룬±£´æÆðʼֵ£¬²¢½«ÏàÓ¦µÄ´úÂë²åÈëµ½·½·¨µÄºÏÊÊλÖá£Ê¹µÃÎÒÃǵĴúÂë¸ü¼ÓÕû½àºÍÈÝÒ×ά»¤¡£

ËÄ ×ܽá
±¾Îļòµ¥½éÉÜÁËÔÚ.NET ÖÐÓÃÀ´½øÐз½·¨²ÎÊýÑéÖ¤µÄ¸÷ÖÖ·½Ê½£¬°üÀ¨´«Í³µÄÔÚ·½·¨Ö´ÐÐǰ±àдÅжÏÓï¾ä£¬ÌáÈ¡µ½¹«¹²°ïÖúÀàÖУ¬Ê¹ÓÃÀ©Õ¹·½·¨£¬ÒÔ¼°Ò»Ð©Àà¿âÈçEnterprise
Liberary£¬PostSharp£¬ASP.NET MVCÈ»ºóʵÏÖÁËÒ»¸ö¼òµ¥µÄÀûÓÃ×Ô¶¨ÒåÊôÐÔÀ´½øÐз½·¨²ÎÊýÑéÖ¤µÄÀý×Ó£¬×îºó½éÉÜÁËÒ»ÏÂ.NET
4.0ÖÖµÄCode Contract£¬ÔÚ¿ª·¢ÖÐÕâЩÑéÖ¤·½Ê½Äܹ»Í³Ò»ÎÒÃǵķ½·¨²ÎÊýÑéÖ¤£¬ÔÚÒ»¶¨µÄ³ÌÐòÉÏ¿ÉÒÔ¼õÉÙ¹¤×÷Á¿£¬Ï£Íû±¾ÎĶÔÄúÓÐËù°ïÖú¡£
|