R#6: InstantHandleAttribute
Dear R# Team,
Thanks for the 6th major release - really enjoy the results of your work.
Have an issue with the InstantHandleAttribute: it would be nice to have a way to tell the engine (maybe through InstantHandleAttribute of via some NotInstantHandleAttribute) that the method which takes an IEnumerable as a parameter DOES NOT enumerate it.
Here is the reason:
I have a helper class Assure that validates my parameters via ValidateArgument<T> method:
/// <summary>
/// This class is a defensive programming helper class.
/// It allows to validate objects (i.e. check for null etc.)
/// as well as to check other conditions to prevent unnecessary
/// exceptions.
/// </summary>
public static class Assure
{
/// <summary>
/// Checks if passed Value is non-empty
/// if not - throws either ArgumentNullException or ArgumentException
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="inArgument">Value to be checked</param>
/// <param name="inArgumentName">Argument name going to be a part of ArgumentNullException</param>
/// <exception cref="System.ArgumentException">Thrown if passed value is empty</exception>
[AssertionMethod]
public static void ValidateArgument<T>(
[AssertionCondition(AssertionConditionType.IS_NOT_NULL)] T inArgument,
[InvokerParameterName] String inArgumentName) where T : class
{
if (inArgument != null)
return;
String tmpCallingMethodName = ExecutionStackHelper.GetMethodName(1);
String tmpErrorMessage = String.Format(
"{0}(): Object argument {1} is empty", tmpCallingMethodName, inArgumentName);
TraceHelper.TraceMessageWithCallStack(tmpErrorMessage);
throw new ArgumentException(
String.Format("{0}(): Object argument is empty", tmpCallingMethodName), inArgumentName);
}
}
If I use it against enumerable arguments, for example:
protected override void DoOnInsertRange(Int32 inIndex, IEnumerable<T> inItems)
{
Assure.ValidateArgument(inItems, "inItems");
foreach (T tmpItem in inItems)
....
}
I get the "Possible multiple enumerations of IEnumerable" error.
Looks like the engine got confused by Assure.ValidateArgument(inItems, "inItems") call - it thinks I iterate there.
I understand that I could have used the [NotNull] on the inItems parameter itself, but the Assure class is used everywhere - can't really make such a global change.
Also, the ValidateArgument<T> could be made non-generic, but in this case it's possible to call it on value types - don't want to lose that.
What would you suggest as a solution?
Regards,
Phil.
Please sign in to leave a comment.
Hello Phil,
Thank you for feedback! I've logged this as a feature request: http://youtrack.jetbrains.net/issue/RSRP-273689
and you're welcome to montor its status.
Andrey Serebryansky
Senior Support Engineer
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"