Is it possible to check the value of a parameter natively using an attribute? I have seen some system attributes like [FromUri] used this way. I'm hoping for something like this:
public void Method([NotNull] string name, [NotNull] DateTime? date)
{ }
where NotNull is an attribute that checks the value to see if it is null. If the value is null it will throw an error.
Here is what I currently have
I'm currently using a static helper class that takes an expression and the parameter itself to determine whether the value is null and uses the expression to determine the name of the parameter.
// Invoke method within ArgumentHelper class
ArgumentHelper.RequireNotNullOrEmpty(() => state, state);
// Method within static class ArgumentHelper
public static void RequireNotNullOrEmpty<T>(this Expression<Func<T>> argumentExpression, string value)
{
var body = ((MemberExpression)argumentExpression.Body);
if (string.IsNullOrEmpty(value))
{
// Throw error "Required field '" + body.Member.Name + "' is missing.";
}
}
Bonus: It would also be nice if I could somehow get the name of the variable without passing a string with its name, just like my current solution.
Definitely not the most performant, but you're on the right track. Here's a wrapper that does a little of what PostSharp would be doing in IL. This is only good for passing objects, it breaks down as is when passing another method as a parameter. However, fixing that problem is just a little more work.
In production I would expand this to build the reflection into a delegate that I could cache for later use.
public class SomeClass
{
public void Method([NotNull] string Param1, [NotNull] string Param2)
{ }
}
public static class SomeClassExtensions
{
public static void InvokeWithNullCheck<TObject>(this TObject obj, Expression<Action<TObject>> expression)
{
var body = (MethodCallExpression)expression.Body;
foreach(var parameter in body.Method.GetParameters())
{
bool hasNotNullAttribute = parameter.CustomAttributes.Any(x => x.AttributeType.Equals(typeof(NotNullAttribute)));
if(hasNotNullAttribute && ((ConstantExpression)body.Arguments[parameter.Position]).Value == null)
{
throw new ArgumentException(String.Format("Mandatory parameter {0} was not supplied.", parameter.Name));
}
}
expression.Compile()(obj);
}
}
[TestFixture]
public class SomeClassTests
{
[Test]
public void Test()
{
var test = new SomeClass();
Assert.Throws<ArgumentException>(() => test.InvokeWithNullCheck(x => x.Method(null, "Test")));
}
}
Take a look at PostSharp (see: http://www.postsharp.net). It provides a lot of attributes like that one you are looking for.
PostSharp is a precompiler which will lookup the attributes in your code and generate appropriate code like parameter validation.
Related
there's any way to get attribute info from parameter of type extension methode ?
For example :
I have an Attribute like this :
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MyAttribute: Attribute
{
public MyAttribute(string _mystring)
{
myString= _mystring;
}
public string myString{ get; set; }
}
So,I have a property like this :
[MyAttribute("TestInt")]
public int MyInt;
and an extension methode like this :
public static void Execute(ref this int t)
{
//Get Attribute info here
Console.WriteLine(t);
}
and I wanna use it like this
MyInt.Execute();
Can i get the Attribute info in the Execute methode ?
The short answer is "no".
An int of ref int is just that value/reference - it doesn't carry with it the metadata context to understand things like attributes.
The only way I can think of for conveying that would be "expressions"; consider:
var obj = new Foo { MyInt = 42 };
SomeUtil.Execute(() => obj.MyInt);
where Execute is:
static class SomeUtil
{
public static void Execute(Expression<Func<int>> t)
{
// investigate the attributes (only supports very simple scenarios currently)
if (t.Body is MemberExpression me)
{
foreach (var attrib in me.Member.GetCustomAttributes<MyAttribute>())
{
Console.WriteLine(attrib.myString);
}
}
// show the value
Console.WriteLine(t.Compile()());
}
}
This will work, but is very inefficient - it involves building an expression tree at the call-site each time, and then investigating that expression tree. Plus it also materializes the attribute instances each time. There are scenarios where this might be OK, but in the general case: definitely worth avoiding.
I want to implement this method from MOQ. (Little out of my depth here)
ISetup<T> Setup(Expression<Action<T>> expression);
public class Foo {
public string Bar { get; set; }
public int Baz { get; set; }
}
public class MyCoolClass
{
public ? Evaluate<Expression<Action>>(expression);
//I want to be able to access and test the value of Foo.Bar (see below)
}
public class ClientOfMyClass
{
public void UseTheMethod()
{
MyCoolClass myCool = new MyCoolClass();
bool result = myCool.Evaluate<Foo>(f => f.Bar);
}
}
Basically, I am trying to write a method that will allow the caller to specify a property on an object with an expression, and allow me to test the value of that property and do something with it.
You want to use an Expression<Func<>> parameter, and check that it contains a Body, and a Member of type PropertyInfo, and use GetValue() passing your object in.
public static void Evaluate<TObj,TProp>(
this TObj obj,
Expression<Func<TObj, TProp>> expr)
{
var prop = (expr.Body as MemberExpression)?.Member as PropertyInfo;
var val = prop?.GetValue(obj);
if (val != null) {
//Do something
}
}
Note that the above code requires the passed in lambda to point to a Property. If you want to handle Fields as well as Methods, they will come in as different types of Expressions, and you'll want to handle handle them slightly differently. For more context and usage, here's a Fiddle.
Edit: Updated to work with other property types.
I am writing a method (let's call it 'Bar') which accepts many parameters. For convenience sake, I set a default value so developers don't have to specify a bunch of 'null' when invoking my method. In other words, my method's signature looks like this:
public void Bar(string paramA = null, string paramB = null, ... many more parameters omitted...)
The code in my method checks for a null value and ignores the parameter in that case. However, there are some situations where I need to make a distinction between a 'default' null value and a null value deliberately set by the developer.
Here are two sample calls to illustrate what I'm talking about. The first one omits all parameters (and therefore the C# compiler will replace them with null at compile time) and the second sample the developer has decided to specify 'null' for the first parameter.
Bar();
Bar(null);
I have found several articles that talk about using "Option/Some/None" pattern. The best one, in my opinion, is here.
But I am struggling to figure out how I can still provide a 'default' value for developers' convenience. Conceptually, I would like to write something like this:
public void Bar(Option<string> paramA = Option.None)
but the C# compiler complains that 'Option.None' is not a compile-time constant.
C# has the concept of "overloads", which are C# methods with the same name but with different parameters.
private void MethodA(string param1) {
}
private void MethodA(string param1, string param2) {
}
If this is not what you want, you could also use the builder pattern. The Builder could be a struct to reduce memory allocations, if you worry about that kind of thing.
var result = new Builder()
.SetParam1(value)
.SetParam2(value)
.Build();
No, there's no way to distinguish them. In fact, the "default" value is baked into the call by the compiler, so
Bar();
and
Bar(null);
result in equivalent IL.
Normally I would recommend overloads instead of defaults but since you have several parameters the number of overload would grow exponentially.
If you need to distinguish between null and a "default" value then you need to use something else as a default.
Another option would be to create a type that could store all parameter values. Then you can tell if a "parameter" was set to null versus being null by default since you can hook into the property setters.
That's essentially what Nullable is for. Although it is used for structs you might create your own wrapper class that does the same thing (with cast operators and such).
For example, you could create Argument<T> that looks and acts like a T but has a property called Set that returns a bool.
Then you could define your method:
public void Bar(Argument<string> paramA = null, ...)
Here's a full example, but I have to admit I'm not happy with it. It seems I can't get the implicit cast operator to be honored when passed as an argument. I had thought C# added this kind of coercion a few years back when they did covariant and contravariant casts. Maybe I misremembered. So it still requires a cast (which I'm doing through an extension method).
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Calling Foo(default(string).ToArg())...");
Foo(default(string).ToArg());
Console.WriteLine("Calling Foo(((string)null).ToArg())...");
Foo(((string)null).ToArg());
Console.WriteLine("Calling Foo(\"test\".ToArg())...");
Foo("test".ToArg());
Console.WriteLine("Calling Foo()...");
Foo();
Console.ReadLine();
}
public static void Foo(Argument<string> arg1 = null)
{
Console.WriteLine("arg1 is {0}null", arg1 == null ? "" : "not ");
Console.WriteLine("arg1.IsSet={0}", arg1?.IsSet ?? false);
Console.WriteLine("arg1.Value={0}", arg1?.Value ?? "(null)");
}
}
public class Argument<T>
{
public Argument()
{
IsSet = false;
}
public Argument(T t)
{
_t = t;
IsSet = true;
}
private T _t;
public T Value { get { return _t; } set { _t = value; IsSet = true; } }
public bool IsSet { get; private set; }
public static implicit operator T(Argument<T> t) { return t._t; }
}
public static class Extensions
{
public static Argument<string> ToArg(this string s) { return new Argument<string>(s); }
}
Depending on the type, you would do something like this:
public static void Bar(string a = "", int b = 0) {
because they are both no value, but still nullable optionally.
For boolean values, I would just default to false, since boolean values are non-nullable.
so:
public static void Bar(string a = "", int b = 0) {
if (a == "") {
// if there is no parameter
}
else {
// stuff
}
if (b == 0) {
// no param
}
else {
// stuff
}
Hope I helped!
I am building a simple Guard API to protect against illegal parameters being passed to functions and so on.
I have the following code:
public static class Guard
{
public static GuardArgument<T> Ensure<T>(T value, string argumentName)
{
return new GuardArgument<T>(value, argumentName);
}
}
public class GuardArgument<T>
{
public GuardArgument(T value, string argumentName)
{
Value = value;
Name = Name;
}
public T Value { get; private set; }
public string Name { get; private set; }
}
// Example extension for validity checks
public static GuardArgument<T> IsNotNull<T>(this GuardArgument<T> guardArgument, string errorMessage)
{
if (guardArgument.Value == null)
{
throw new ArgumentNullException(guardArgument.Name, errorMessage);
}
return guardArgument;
}
At the moment the code can be used in a similar way to (note this is just a dumb example):
void DummyMethod(int? someObject) {
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.IsGreaterThan(0)
.IsLessThan(10);
}
This all works fine. What I want to be able to do now is extend the API to include child properties in the checks in the following way:
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.Property(
(x => x.ChildProp1, "childProp1")
.IsNotNull()
.IsGreaterThan(10)
)
.Property(
(x => x.ChildProp2, "childProp2")
.IsNotNull()
.IsLessThan(10)
);
Obviously the new .Property method needs to return the parent GuardArgument in order to chain. Furthermore the child property needs to be able to use the existing check methods (IsNotNull() etc) to avoid code duplication.
I cannot work out how to construct the lambda/Property function parameters or where the .Property method should be located - i.e. should it be a property on the GuardArgument or somewhere else, or even if there is a better structure to the API.
The following function allows for a similar syntax to what you want.
public static GuardArgument<T> Property<T, TProp>(this GuardArgument<T> guardArgument, Func<T, TProp> getProperty, string propertyName, Action<GuardArgument<TProp>> validate)
{
GuardArgument<TProp> propertyGuardArgument = new GuardArgument<TProp>(getProperty(guardArgument.Value), propertyName);
validate(propertyGuardArgument);
return guardArgument;
}
The function creates a new GuardArgument for the selected property and then passes this into the Action parameter to allow you to validate as you wish.
This also allows infinite chaining of properties, although I'm not sure that would be particularly readable.
Usage:
Guard.Ensure(someObject, "someObject")
.IsNotNull()
.Property(x => x.ChildProp1, "childProp1", childProp1 =>
childProp1.IsNotNull()
.IsLessThan(10)
.Property(y => y.InnerChildProperty, "innerChildProperty", innerChildProperty =>
innerChildProperty.IsNotNull()
)
)
.Property(x => x.ChildProp2, "childProp2", childProp2 =>
childProp2.IsNotNull()
.IsGreaterThan(10)
);
I think you have no benefit from putting the property checks in the chain of the parent object checks. So I would recommend to make one chain for the parent object and for each property another chain. This is much more readable:
Guard.Ensure(a, "a")
.IsNotNull("a is null");
Guard.Ensure(a.p0, "a.p0")
.IsGreaterThan(10);
Guard.Ensure(a.p1, "a.p1")
.IsGreaterThan(5);
I think you are reinventing a wheel here. Install this extension - Code Contracts and here is docs how to use it.
In addition to code based asserts similar to yours, i.e. :
public int[] Bar(){
Contract.Ensures( Contract.ForAll(0, Contract.Result<int[]>().Length, index => Contract.Result<int[]>()[index] > 0));
....
}
or
Contract.Requires<ArgumentNullException>( x.Value.NestedObject != null, ”x.Value.NestedObject” );
But also has attributes and extensive set of functions for checking interfaces, nice pre- and post- conditions etc. check it out!
You all do this:
public void Proc(object parameter)
{
if (parameter == null)
throw new ArgumentNullException("parameter");
// Main code.
}
Jon Skeet once mentioned that he sometimes uses the extension to do this check so you can do just:
parameter.ThrowIfNull("parameter");
So I come of with two implementations of this extension and I don't know which one is the best.
First:
internal static void ThrowIfNull<T>(this T o, string paramName) where T : class
{
if (o == null)
throw new ArgumentNullException(paramName);
}
Second:
internal static void ThrowIfNull(this object o, string paramName)
{
if (o == null)
throw new ArgumentNullException(paramName);
}
What do you think?
I tend to stick to the ubiquitous Guard class for this:
static class Guard
{
public static void AgainstNulls(object parameter, string name = null)
{
if (parameter == null)
throw new ArgumentNullException(name ?? "guarded argument was null");
Contract.EndContractBlock(); // If you use Code Contracts.
}
}
Guard.AgainstNulls(parameter, "parameter");
And shy away from extending object, plus to the naked eye a method call on a null object seems nonsensical (although I know it is perfectly valid to have null method calls against extension methods).
As for which is best, I'd use neither. They both have infinite recursion. I'd also not bother guarding the message parameter, make it optionally null. Your first solution will also not support Nullable<T> types as the class constraint blocks it.
Our Guard class also has the Contract.EndContractBlock() call after it for when we decide to enable Code Contracts, as it fits the "if-then-throw" structure that is required.
This is also a perfect candidate for a PostSharp aspect.
I'd use internal static void ThrowIfNull<T>(this T o, string paramName) where T : class. I won't use internal static void ThrowIfNull(this object o, string paramName) because it might do boxing.
As of .NET 6, now we have the static method ThrowIfNull in the System.ArgumentNullException class with the following signature:
ThrowIfNull(object? argument, string? paramName = null);
Therefore, instead of writing:
if (value == null)
{
throw new System.ArgumentNullException(nameof(value));
}
Now we can simply write:
System.ArgumentNullException.ThrowIfNull(value);
The docs: https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-6.0
The implementation of this new method takes advantage of the System.Runtime.CompilerServices.CallerArgumentExpressionAttribute attribute to simplify this further, by not requiring the developer to explicitly provide the name of the parameter that's being guarded.
The discussion that ended up introducing this new API can be found here:
https://github.com/dotnet/runtime/issues/48573
The PR that introduced it in the .NET 6 code base can be found here:
https://github.com/dotnet/runtime/pull/55594
I would do this way to avoid hardcoding parameter names. Tomorrow it can change, and you have more work then:
public static void ThrowIfNull<T>(this T item) where T : class
{
var param = typeof(T).GetProperties()[0];
if (param.GetValue(item, null) == null)
throw new ArgumentNullException(param.Name);
}
And call it:
public void Proc(object parameter)
{
new { parameter }.ThrowIfNull(); //you have to call it this way.
// Main code.
}
The performance hit is trivial (on my mediocre computer it ran for 100000 times just under 25 ms), much faster than Expression based approach seen typically
ThrowIfNull(() => resource);
One such here. But surely don't use this if you cant afford that much hit..
You can also extend this for properties of objects.
new { myClass.MyProperty1 }.ThrowIfNull();
You can cache property values to improve performance further as property names don't change during runtime.
See this question additionally: Resolving a parameter name at runtime
What about using Expression Trees (from Visual Studio Magazine):
using System;
using System.Linq.Expressions;
namespace Validation
{
public static class Validator
{
public static void ThrowIfNull(Expression<Func<object>> expression)
{
var body = expression.Body as MemberExpression;
if( body == null)
{
throw new ArgumentException(
"expected property or field expression.");
}
var compiled = expression.Compile();
var value = compiled();
if( value == null)
{
throw new ArgumentNullException(body.Member.Name);
}
}
public static void ThrowIfNullOrEmpty(Expression<Func<String>> expression)
{
var body = expression.Body as MemberExpression;
if (body == null)
{
throw new ArgumentException(
"expected property or field expression.");
}
var compiled = expression.Compile();
var value = compiled();
if (String.IsNullOrEmpty(value))
{
throw new ArgumentException(
"String is null or empty", body.Member.Name);
}
}
}
}
Used like this:
public void Proc(object parameter1, object parameter2, string string1)
{
Validator.ThrowIfNull(() => parameter1);
Validator.ThrowIfNull(() => parameter2);
Validator.ThrowIfNullOrEmpty(() => string1);
// Main code.
}
Based on C# 10, I use the ThrowIfNull extension method:
public static class CheckNullArgument
{
public static T ThrowIfNull<T>(this T argument)
{
ArgumentNullException.ThrowIfNull(argument);
return argument;
}
}
Usage:
public class UsersController
{
private readonly IUserService _userService;
public UsersController(IUserService userService)
{
_userService = userService.ThrowIfNull();
}
}
Second one seems more elegant way of handling the same. In this case you can put restriction on every managed object.
internal static void ThrowIfNull(this object o, string paramName)
{
if (o == null)
throw new ArgumentNullException(paramName);
}