I have the following extension method:
public static void ThrowIfArgumentIsNull(this T value, string argument)
where T : class
{
if (value
I would recommend that you rather do the following:
public static void ThrowIfArgumentIsNull(this object value, string argument)
{
if (value == null)
{
throw new ArgumentNullException(argument);
}
}
Using generics in this case doesn't seem to add any value. But as to your original question, I don't think that's possible.
I like Enforce from the Lokad Shared Libraries.
Basic syntax:
Enforce.Arguments(() => controller, () => viewManager,() => workspace);
This will throw an exception with the parameter name and type if any of the arguments is null.
See also ArgumentNullException and refactoring for a complete solutions along the same lines as the answer.
What about:
public void Save(Category qwerty)
{
ThrowIfArgumentIsNull( () => return qwerty );
qwerty.ThrowIfArgumentIsNull("qwerty");
// ....
}
then define ThrowIfArgumentIsNull as
public static void ThrowIfArgumentIsNull(Expression<Func<object>> test)
{
if (test.Compile()() == null)
{
// take the expression apart to find the name of the argument
}
}
sorry I don't have the time to fill in the detail or provide the full code at present.
In a word: no.
The extension method is passed a value. It has no idea where the value comes from or what identifier the caller may have choosen to refer to it as.
I find it easiest to do this using a code snippet.
In your example, I can type tna<tab>qwerty<enter>
.
Here is the snippet:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>Check for null arguments</Title>
<Shortcut>tna</Shortcut>
<Description>Code snippet for throw new ArgumentNullException</Description>
<Author>SLaks</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
<SnippetType>SurroundsWith</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>Parameter</ID>
<ToolTip>Paremeter to check for null</ToolTip>
<Default>value</Default>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[if ($Parameter$ == null) throw new ArgumentNullException("$Parameter$");
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
No, you can't do this. It would be nice, but it's not possible without some sort of AOP getting involved. I'm sure PostSharp can do a nice job, hopefully using attributes, and in Code Contracts it would just be:
Contract.Requires(qwerty != null);
Ideally I'd like a PostSharp attribute which generates the Code Contracts call - and I'll play around with that at some point - but until then, the extension method you've got is the best approach I've found...
(If I ever try the PostSharp + Code Contracts approach, I'll certainly blog about it, btw... Mono Cecil might make it reasonably easy too.)
EDIT: To expand on Laurent's answer, you could potentially have:
new { qwerty }.CheckNotNull();
And if you had lots of non-nullable parameters, you could have:
new { qwerty, uiop, asdfg }.CheckNotNull();
This would have to use reflection to work out the properties. There are ways that you could avoid doing the reflection on every access, building a delegate for each property and generally making it whizzy. I may investigate this for a blog post... but it's somewhat icky, and I prefer the idea of being able to just attribute the parameters...
EDIT: Code implemented, and blog post duly made. Ick, but fun