You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Example code for argumkent validation in EmbedIO.Utilities v4.0.
#nullable enable
using System;using System.Diagnostics.CodeAnalysis;using EmbedIO.Utilities.ArgumentValidation;// <-- Here's what you need// Additional checks are in the same namespace as types they are related tousing EmbedIO.Utilities.IO;// For LocalPathusing EmbedIO.Utilities.Web;// For HttpToken, MimeType, UrlPathnamespace Example;publicstaticclassDemonstrate{// =======================================================================// ARGUMENTS OF NON-NULLABLE REFERENCE TYPES// =======================================================================publicstaticvoidNonNullableReferenceArguments(stringstr,IDisposableobj,EventHandlerfunc){// Ensure that an argument is not null.// You don't need nameof(str) - what you pass as parameter "becomes" its name in exceptions._= Arg.NotNull(str);// From here on, s1 is certainly not null (and Code Analysis knows it too)// The result is a "ref struct" that is implicitly convertible to the type of the argument,// so you can use it in an expression, assign it, etc.// Not useful in this case as it's the same as "str = str"...str= Arg.NotNull(str);// Also not useful here, because you are using the helper struct itself, not the value of the argument.varx= Arg.NotNull(str);// The type of x is NOT string!// ...but useful here.// This is not magic: an implicit conversion operator does the work.
Console.WriteLine(Arg.NotNull(str));// Implicit conversion does not work in all contexts:// for instance, if the type of the argument is an interface or a delegate.// You can achieve the same result with the Value property.
Arg.NotNull(obj).Dispose();// Error
Arg.NotNull(obj).Value.Dispose();// OKsomeEvent+= Arg.NotNull(func);// ErrorsomeEvent+= Arg.NotNull(func).Value;// OK// Note that // Shortcut methods for string arguments.// Obviously you normally don't use Arg twice on the same argument - this is just for demostration purposes._= Arg.NotNullOrEmpty(str);_= Arg.NotNullOrWhiteSpace(str);// Further checks can be performed.// For example, let's ensure str is a valid local file system path._= Arg.NotNull(str).LocalPath();// You can optionally get the full path.// Note that, unlike the old Validate.LocalPath, we never modify the passed argument value;// "derived" values, such as fullPath here, are out parameters._= Arg.NotNull(str).LocalPath(outvar fullPath);
System.Console.WriteLine(fullPath);// Perform a custom check using a lambda._= Arg.NotNull(str).Check(s => s.Length >4,"Argument must be longer than 4 characters.");// Custom check with custom message(s)// Your lambda takes a value and an out reference to the message; returns true for success, false for failure._= Arg.NotNull(str).Check((s,[MaybeNullWhen(true)]outm)=>{if(s.Length <4){m="Argument must be at least 4 character long.");returnfalse;}if(s.Length >8){m="Argument must be at most 8 character long.");returnfalse;}returntrue;});// Of course you can use a method or even a local function instead of a lambda.staticboolHasCorrectLength(stringstr,[MaybeNullWhen(true)]outstringmessage){if(str.Length <4){message="Argument must be at least 4 character long.");returnfalse;}if(str.Length >8){message="Argument must be at most 8 character long.");returnfalse;}returntrue;}// Use the above local function_= Arg.NotNull(str).Check(HasCorrectLength);// Of course you may chain as many checks as necessary._= Arg.NotNull(str).Check(HasCorrectLength).LocalPath();}// =======================================================================// ARGUMENTS OF NULLABLE REFERENCE TYPES// =======================================================================publicstaticvoidNullableReferenceArguments(string?str){// Correct, although it does nothing useful by itself_= Arg.Nullable(str);// You can obviously chain further checks after Nullable._= Arg.Nullable(str).NotEmpty();// Null is valid; empty string causes ArgumentException// You can use the same checks you use on non-nullable types,// while always considering null a valid value._= Arg.Nullable(str).CheckUnlessNull(s => s.Length >4,"Argument should be null or longer than 4 characters.");// Need to test for a condition that includes null as a valid value?// Just use a lambda (or method, or local function) that takes a bool and a nullable value// and returns true if the argument value is valid, false otherwise.// The first parameter passed to the lambda is true if the argument's value is not null._= Arg.Nullable(str).Check((hasValue,s)=>hasValue|| DateTime.Now.DayOfWeek != DayOfWeek.Monday,"Argument should be non-null on a Monday");// Don't you hate Mondays too?// Of course you also have the option of returning mthe exception message from your check method._= Arg.Nullable(str).Check((hasValue,s,[MaybeNullWhen(true)]outmessage)=>{message=hasValue|| DateTime.Now.DayOfWeek != DayOfWeek.Monday?"Argument should be non-null on a Monday":null;return message is not null;});}// -----------------------------------------------------------------------// Custom check method// -----------------------------------------------------------------------privatestaticboolIsAcceptableToday(boolhasValue,stringstr,[MaybeNullWhen(true)]outstringmessage){// We want null on weekends, no more than 20 characters on workdays.message= DateTime.Now.DayOfWeek switch{
DayOfWeek.Saturday or DayOfWeek.Sunday =>hasValue?"Argument should be null on weekends.":null,
_ =>!hasValue?"Argument should not be null on workdays.": str.Length >20?"Argument should not be longer than 20 characters.":null,}
return message isnull;}// =======================================================================// ARGUMENTS OF (NON-NULLABLE) VALUE TYPES// =======================================================================publicstaticvoidNonNullableValueArguments(intnum){// Correct, although it does nothing useful by itself_= Arg.Value(num);// You can obviously chain further checks after Value.// Standard comparisons work with any struct implementing IComparable<itself>;// the exception message will contain the string representation of the threshold// or range bounds, so if you plan to use these checks for your own types// you should override ToString() to provide a meaningful representation.// You don't want "Argument should be greater than {MyStruct}." as an exception message._= Arg.Value(num).GreaterThan(50);_= Arg.Value(num).GreaterThanOrEqualTo(2);_= Arg.Value(num).LessThan(1000);_= Arg.Value(num).LessThanOrEqualTo(500);_= Arg.Value(num).InRange(1,5);// Open range (both 1 and 5 are valid)_= Arg.Value(num).GreaterThanZero();// Custom checks.// Needless to say, you may use methods or local functions instead of lambdas// if you need reusable checks._= Arg.Value(num).Check(n =>(n&1)==0,"Argument should be an even number.");_= Arg.Value(num).Check((n,[MaybeNullWhen(true)]outmessage)=>{message=(n%3)==0?null:(n%7)==0?null:"Argument should be divisible by 3 and/or by 7.";return message is not null;});}// =======================================================================// ARGUMENTS OF NULLABLE VALUE TYPES// =======================================================================publicstaticvoidNonNullableValueArguments(int?num){// Correct, although it does nothing useful by itself_= Arg.Nullable(num);// You can obviously chain further checks after Nullable.// Just like with nullable reference types, null is always considered valid._= Arg.Nullable(num).GreaterThan(50);_= Arg.Nullable(num).GreaterThanOrEqualTo(2);_= Arg.Nullable(num).LessThan(1000);_= Arg.Nullable(num).LessThanOrEqualTo(500);_= Arg.Nullable(num).InRange(1,5);// Open range (both 1 and 5 are valid)_= Arg.Nullable(num).GreaterThanZero();// Custom checks.// Needless to say, you may use methods or local functions instead of lambdas// if you need reusable checks._= Arg.Value(num).CheckUnlessNull(n =>(n&1)==0,"Argument should be null or an even number.");// Need to test for a condition that includes null as a valid value?// Meet NullablePredicate, that takes a bool and a nullable value and returns true if successful.// The first parameter passed to the lambda is true if the argument's value is not null._= Arg.Nullable(str).Check((hasValue,s)=>hasValue|| DateTime.Now.DayOfWeek != DayOfWeek.Monday,"Argument should be non-null on a Monday");// Don't you hate Mondays too?// Custom check with nullability and custom messages._= Arg.Value(num).Check((hasValue,n,[MaybeNullWhen(true)]outmessage)=>{message=hasValue?null DateTime.Now.DayOfWeek != DayOfWeek.Monday ?null:"Argument should be non-null on a Monday.";return message is not null;});}}
Comments, criticisms, and questions are heartily welcome.
The text was updated successfully, but these errors were encountered:
FYI, the .NET Community Toolkit has Guard and Throw Helper APIs for a similar purpose (though not setup to chain), but are optimized for the codegen. FYI @Sergio0694 if there's questions.
Example code for argumkent validation in
EmbedIO.Utilities
v4.0.Comments, criticisms, and questions are heartily welcome.
The text was updated successfully, but these errors were encountered: