patterncsharpMinor
Using an extension method for a small helper task that (ab)uses the fact that the object is not dereferenced
Viewed 0 times
dereferencedthefactmethodhelperusesextensionsmallforusing
Problem
I've recently got into an habit where I've used extension methods for giving things fluent-like properties - such as the below example or as another example
This is then used as follows:
as opposed to
Do you think this is readable? Is it in any way preferable to regular checks everywhere? The fact that I can't really decide if I like it or not makes me nervous, so I'd like some external input!
UPDATE:
Yes, you made me open my eyes. Hopefully, you will agree with me that the following is a bit more agreeable. I used expressions because I want to include as much information as possible in the exception.
Atleast I think this makes it a bit clearer, even though the lambda syntax is not very nice (I don't think
Since I compile the expression each time, there will surely be some performance penalty.
entity.AssertNotNull()public static class GenericHelper
{
public static void AssignOrThrowIfNull(this T obj, ref T assignTo, string paramName)
{
if (obj == null)
throw new ArgumentNullException(paramName, "Unallowed null argument of type: " + typeof(T).FullName);
assignTo = obj;
}
}This is then used as follows:
public class SmtpClient
public SmtpServerAddress Server
{
get { return smtpServer; }
}
private SmtpServerAddress smtpServer;
public SmtpClient(SmtpServerAddress smtpServer)
{
smtpServer.AssignToOrThrow(ref this.smtpServer, "smtpServer");
}as opposed to
public SmtpClient(SmtpServerAddress smtpServer)
{
if(smtpServer == null)
throw new ArgumentNullException("smtpServer");
}Do you think this is readable? Is it in any way preferable to regular checks everywhere? The fact that I can't really decide if I like it or not makes me nervous, so I'd like some external input!
UPDATE:
Yes, you made me open my eyes. Hopefully, you will agree with me that the following is a bit more agreeable. I used expressions because I want to include as much information as possible in the exception.
public static class Require
{
public static void That(Expression> func)
{
if (!func.Compile()())
throw new ContractException("Contract not fulfilled: " + func.Body, func);
}
}Atleast I think this makes it a bit clearer, even though the lambda syntax is not very nice (I don't think
smtpServer != null can be inferred to an Expression).Require.That(() => smtpServer != null);
SmtpServer = smtpServer;Since I compile the expression each time, there will surely be some performance penalty.
Solution
You might want to look into code contracts instead, which allows you to write:
This expresses clearly what you are trying to do, and has the added advantage of allowing additional static checking by the code contracts tool to check the code that calls your method for possible violations of the contract.
Contract.Requires(smtpServer != null);This expresses clearly what you are trying to do, and has the added advantage of allowing additional static checking by the code contracts tool to check the code that calls your method for possible violations of the contract.
Code Snippets
Contract.Requires<ArgumentNullException>(smtpServer != null);Context
StackExchange Code Review Q#3352, answer score: 3
Revisions (0)
No revisions yet.