I am I am using C# 7+, and I am aware of the [CallerMemberName]
attribute, but what I am looking for is an attribute that would get me the name of an argument.
Use case: Checking for null, even with the ??
and ?
null operators, can be a bit tedious with the condition checks and throwing the proper exceptions with the proper values. For a few months now I've been using a solution inspired by some article I read and that could be described as an "argument validation builder". It would be used something like this:
public class MyClass
{
public void DoTheThing(IFoo foo, ICollection<IBar> bars, string specialText)
{
new ArgumentValidator()
.NotNull(foo, nameof(foo))
.NotNullOrEmpty(bars, nameof(bars))
.NotNullOrEmpty(specialText, nameof(specialText));
...rest of function
}
}
If, for example, foo
was null, then ArgumentValidator.NotNull(...)
would throw a new ArgumentNullException
with the parameter name "foo". This approach makes argument checking a bit more concise, and that's pretty much the only reason I'm doing this.
It would be really nice if I didn't have to specify nameof(...)
every single time. That is, I'd like to be able to do this:
new ArgumentValidator()
.NotNull(foo)
.NotNullOrEmpty(bars)
.NotNullOrEmpty(specialText);
In order to do that though, I would need to figure how to make the NotNull(...)
and other functions figure out the name of the argument.
I've tried making a parameter-based attribute, I've tried looking at Environment.StackTrace
(not thrilled about trying to parse that nor about the performance implications), I've looked at StackFrame
, I've looked at getting type info about the class -> method info -> parameter info and the custom attributes, and I still haven't found a way forward.
I'd like to make an attribute similar to [CallerMemberName]
, but this attribute would extract the name of the argument that was used to call the function, assign it to the decorated parameter, and would performs quickly (in other words, I want to avoid stack trace stuff if possible, especially since I'm using these checks a lot).
This is where I'm at:
[AttributeUsage( AttributeTargets.Parameter )]
class ArgumentNameAttribute : Attribute
{
public string SomeProperty { get; set; }
}
class Program
{
static void NotNull<T>( T argument, [ArgumentNameAttribute] string argumentName )
{
//how to get at the argumentName?
}
static void DoTheThing( string thing )
{
NotNull( thing );
Console.WriteLine( "hello world" );
}
static void Main( string[] args )
{
DoTheThing( "12345" );
}
}
Alternately, I'll accept another solution that makes argument checking concise and expressive.
Ideas?
Aucun commentaire:
Enregistrer un commentaire