Imagine someone coding the following:
string s = "SomeString";
s.ToUpper();
We all know that in the example above, the call to the “ToUpper()” method is meaningless because the returned string is not handled at all. But yet, many people make that mistake and spend time trying to troubleshoot what the problem is by asking themselves “Why aren’t the characters on my ‘s’ variable capitalized”????
So wouldn’t it be great if there was an attribute that could be applied to the “ToUpper()” method that would yield a compiler error if the return object is not handled? Something like the following:
[MustHandleReturnValueAttribute]
public string ToUpper()
{
…
}
If order for this code to compile correctly the user would have to handle the return value like this:
string s = "SomeString";
string uppers = s.ToUpper();
I think this would make it crystal clear that you must handle the return value otherwise there is no point on calling that function.
In the case of the string example this may not be a big deal but I can think of other more valid reasons why this would come in handy.
What do you guys think?
Thanks.
Does one call a method for its side-effects, for its return value, or for both? "Pure" functions (which have no effects and only serve to compute a return value) would be good to annotate as such, both to eliminate the type of error you describe, as well as to enable some potential optimizations/analyses. Maybe in another 5 years we'll see this happen.
(Note that the F# compiler will warn any time you implicitly ignore a return value. The 'ignore' function can be used when you want to explicitly ignore it.)
If you have Resharper it will highlight things like this for you. Cant recommend resharper highly enough, it has lots of useful IDE additions especially around refactoring.
http://www.jetbrains.com/resharper/
I am not sure that I like this. I have called many a method that returns a value that I choose not to capture. Adding some type of default (the compiler generates a warning when a return value is not handled) just seems wrong to me.
I do agree that something along the suggested lines might help out new programmers but adding an attribute at this point in the game will only affect a very small number of methods relative the the large existing body. That same junior programmer will never get their head around the issue when most of their unhandled return values are not flagged by the compiler.
Might have been nice way back when but the horses are out of the barn.
I'd actually prefer a way to flag a struct or class as [Immutable], and have this handled automatically (with a warning) for methods called without using their return values on immutable objects. This could also protect the object by the compiler from changes after creation.
If the object is truly an immutable object, there really would be no way to handle it. It also could potentially be used by compilers to catch other common mistakes.
Tagging the method itself seems less useful to me, though. I agree with most of the other comments regarding that. If the object is mutable, calling a method could have other side-effects, so the above code could be perfectly valid.
I'm having flashbacks to putting (void) casts on all printf() calls because I couldn't get Lint to shut up about the return value being ignored.
That said, it seems like this functionality should be in some code checker tool rather than the compiler itself.
At least a compiler-warning would be helpful. Perhaps they add something similar for C# 4.0 (Design-By-Contract).
This doesn't warrant for a warning or pragma. There are too many places where it is intended to discard the result, and I'd be quite annoyed getting a warning/error from the compiler just because the method was decorated with some dodge attribute.
This kind of 'warning' should be annotated in the IDE's Editor, like a small icon on the gutter "Warning: Discarding return value" or similar.
Related
I have an array of strings and I wish to find out if that array does not contain a certain string. I can use the not operator (!) in conjunction with the Contains method like so:
if (!stringArray.Contains(searchString))
{
//do something
}
The not operator (!) might be overlooked when scanning the code so I was wondering if it was considered bad practice to create an Extension method in an attempt to enhance readability:
public static bool DoesNotContain<T>(this IEnumerable<T> source, T value)
{
return !source.Contains<T>(value);
}
So now the code could read:
if (stringArray.DoesNotContain(searchString))
{
//do something
}
Is this sort of thing frowned upon?
Keep the !. This is where a comment above the line would help readability.
(I suspect ! is more efficient)
//If the word is NOT in the array then...
Another point is to whether you are dead-set on using an Array?
There is something (that you may or may not know about) called a HashSet.
If your sole purpose is to examine whether or not a string is in a list, you are essentially looking at set arithmetic.
Unless you are using the array for something other than finding out whether a certain term is in it or not, try using a HashSet...much faster.
Personally, I wouldn't make an extension method for something so simple. I understand that you're trying to keep it readable but most C# developers should catch the ! operator. It's heavily used and even beginners usually recognize it.
Seems unnecessary, !source.Contains<T>(value); is pretty readable. Also, using the existing Contains function means that your code will be more portable (i.e., it won't be dependent on your extension method being present).
I would definitely use the !stringArray.Contains(string). This what 99.9% of all developers use. DoesNotContain would confuse me at least.
I think your question is based on a bit of a faulty premise. Namely that developers will read past the ! in your code. The ! boolean operator is a very well known operator in a large number of popular programming languages (C, C++, C#, Java, etc ...). Anyone who is likely to read past the ! on a regular basis probably shoudln't be checking in code without a heavy review before hand.
It feels like you`re saying the following
I want people to code in C# but I don't trust them to read it hence I'm going to create a new dialect in my code base with extension methods.
Why stop with the ! operator? It seems just as likely that they would miss the + in += expression or read a | as a ||.
Never seen DoesNot* methods in .NET framework, so I think your problem with ! is overestimated.
I guess this is a personnal choice more than a good/bad practice. IMO I like the extension methods since its more declarative thus more readable, at first glance you know exactly what it does. Just my 2 cents
This sounds like a bad idea, now the consumers of your code have to know about two methods (DoesNotContain and Contains) instead of just one. In general I would avoid XXNotXX methods.
I would personally make an extension method for that if I was going to be using that quite frequently within the project. If it is a one off then i wouldnt bother, but its not really bad practise.
The reason I would do it is because the if() has more context at a glance as to what is going on. Ok granted anyone with a brain cell would know what the current statement is doing, but it just reads nicer. Everyone will have their own preference then...
I made an extension method for formatting strings just to make the code flow better...
I prefer option 1 over option 2. Extension methods are very cool and are great to use for such things as conversions or comparisons that are used frequently. However, Microsoft does recommend to use extension methods sparingly.
I really would consider extension methods which does nothing else than negating an expression as bad practice.
What about:
if (stringArray.Contains(searchString) == false)
{
//do something
}
When !something doesn't work, then fall back to something == false.
Quite often I see source code where language's keyword are replaced with full type names:
System.String, System.Int32, System.GUID etc.
Moreover, people who do this write complete type names everywhere, making source full of such declarations:
System.Collections.Generic.List<System.Reflection.PropertyInfo> list = System.Collections.Generic.List<System.Reflection.PropertyInfo>(newSystem.Reflection.PropertyInfo[] { ... });
When I ask them why do they do this, i get wide range of answers: "It helps me avoid type names collisions", "It looks more professional", "my VS plugin does it for me automatically" etc.
I understand, sometimes writing full type names helps you avoid writing unnecessary using if you use the type one time throughout the source code file. And sometimes you need to declare a type explicitly, a great example is Threading Timer and WinForms Timer.
But if you source full of DB calls and you still write System.Data.SqlClient.SqlCommand instead of 'SqlCommand' it looks quite a bit strange for me.
What do you think? Am i right or i just don't understand something?
Thank you!
P.S. And another phenomena is writing if (0 != variable) instead of if (variable != 0).
The if (0 == variable) thing is a C++ convention used to protect against accidentally writing if (variable = 0), which is valid in C++ however doesn't do what's intended. Its completely unnecessary in C# as the wrong version doesn't compile, so you should use the other version instead as it reads better.
Personally I like to write as little as possible, so unless there is a namespace clash I never fully qualify things.
As for string vs String, I always use the alias (string / int) rather than the full class name, however its purely a convention - there is no runtime difference.
I'd argue strongly against "it looks more professional", as frankly it looks the opposite to me.
That said, if I was to use a single member of a namespace in the entire source file, I might use the full name there rather than have a using.
Favouring 0 != x over x != 0 etc. does have some advantages depending on overrides of equals and a few other things. This is more commonly so in some other languages, so can be a hangover from that. It's particularly common to see people favour putting the null first, as that way it's less likely to be turned into passing null to an equality override (again, more commonly a real issue in other languages). It can also avoid accidental assignment due to a typo, though yet again this is rarely an issue in C# (unless the type you are using is bool).
It is a bit subjective but unless your coding standard says otherwise I think removing the namespace is always better as it is less vebose and makes for easier reading. If there is a namespace collision, use a shorter alias that means something.
As to your last point, if you compare name.Equals("Paul") vs "Paul".Equals(name). They both do the same thing unless name is null. In this case, the first fails with a null exception, whilst the 2nd (correctly?) returns false.
For primitive data types: Duplicate questions here - C#, int or Int32? Should I care?
For non-primitive data types: The answers given are valid, especially "It helps to avoid type names collisions"
For if (0 != variable): variable is the subject to compare in the expression, it should go first. So, I would prefer if (variable != 0).
I don't find any of these reasons convincing. Add using statements is better.
Two minor exceptions:
In generated code, you may see redundant namespace prefixes, but that is OK as this code is not indented to edited.
Sometimes it is helpful to write Int32 explicitly when depend on the type being exactly 32 bits.
Make code as readable as possible! See also: http://en.wikipedia.org/wiki/KISS_principle
"It looks professional" is a very bad argument.
BTW, if your code is full of SQL statements, then you may want to refactor that anyway.
About string vs String. I try to use string, when it is that, i.e. a string of characters as in any programming language. But when it is an object (or I am referring to the String class), I try to use String.
I like readability.
So, I came up with an extension mothod a few minutes ago for the (x =! null) type syntax, called IsNotNull. Inversly, I also created a IsNull extension method, thus
if(x == null) becomes if(x.IsNull())
and
if(x != null) becomes if(x.IsNotNull())
However, I'm worried I might be abusing extension methods. Do you think that this is bad use of Extenion methods?
It doesn't seem any more readable and could confuse people reading the code, wondering if there's any logic they're unaware of in those methods.
I have used a PerformIfNotNull(Func method) (as well as an overload that takes an action) which I can pass a quick lambda expression to replace the whole if block, but if you're not doing anything other than checking for null it seems like it's not providing anything useful.
I don't find that incredibly useful, but this:
someString.IsNullOrBlank() // Tests if it is empty after Trimming, too
someString.SafeTrim() // Avoiding Exception if someString is null
because those methods actually save you from having to do multiple checks. but replacing a single check with a method call seems useless to me.
It is perfectly valid to do but I don't think it is incredibly useful. Since extension methods are simply compiler trickery I struggle to call any use of them "abuse" since they are just fluff anyhow. I only complain about extension methods when they hurt readability.
Instead I'd go with something like:
static class Check {
public static T NotNull(T instance) {
... assert logic
return instance;
}
}
Then use it like this:
Check.NotNull(x).SomeMethod();
y = Check.NotNull(x);
Personally it's much clearer what is going on than to be clever and allow the following:
if( ((Object)null).IsNull() ) ...
I don't entirely agree with the reasoning saying "it may confuse".
To some extent I can see what is meant, that there is no reason to venture outside "common understanding" -- everybody understands object != null.
But in Visual Studio, we have wonderful tools where you can simply hover over the method, to reveal some additional information.
If we were to say that the extension-method was annotated with a good explanation, then I feel that the argument of confusion falls apart.
The methods .IsNotNull() and .IsNull() explain exactly what they are. I feel they are very reasonable and useful.
In all honesty it is a matter of "what you like". If you feel the methods will make it more readable in the context of your project, then go for it. If you are breaking convention in your project, then I would say the opposite.
I have had the same thoughts as you have on the subject and have asked several very very experienced developers at my place of work. And none of them have come up with a good reason (except what has been mentioned about -confusion- here) that would explain why you shouldn't do this.
Go for it :-)
There is precedent, in as much as the string class has IsNullOrEmpty
You're also introducing method call overhead for something that's a CLR intrinsic operation. The JIT might inline it away, but it might not. It's a micro-perf nitpick, to be sure, but I'd agree that it's not particularly useful. I do things like this when there's a significant readability improvement, or if I want some other behavior like "throw an ArgumentNullException and pass the arg name" that's dumb to do inline over and over again.
It can make sense if you, for instance, assume that you might want to throw an exception whenever x is null (just do it in the extension method). However, I my personal preference in this particular case is to check explicitly (a null object should be null :-) ).
To follow the pattern it should be a property rather than a method (but of course that doesn't work with extensions).
Data values in the System.Data namespace has an IsNull property that determines if the value contains a DbNull value.
The DataRow class has an IsNull method, but it doesn't determine if the DataRow is null, it determines if one of the fields in the data row contains a DbNull value.
In some situations using C/C++, I can syntactically indicate to the compiler that a return value is purposely ignored:
int SomeOperation()
{
// Do the operation
return report_id;
}
int main()
{
// We execute the operation, but in this particular context we
// have no use of the report id returned.
(void)SomeOperation();
}
I find this to be a fair practice, firstly because most compilers won't generate a warning here, and secondly because it explicitly shows to future developers that the author made a conscious choice to ignore the return. It makes the author's trail of thought non ambiguous.
As far as I know, the C# compiler won't complain about implicitly ignored return values, but I would like to know if there's a similar convention to use in order to make a clear indication to other developers.
In response to some people here who questions the actual use of this convention (or that it would show bad design to have a method with a potentially unimportant return value).
A real life .NET example (which I maybe should have based the question on from the start) is the Mutex::WaitOne() overload which takes no arguments. It will only return if the mutex was safely acquired, otherwise it never returns. The boolean return value is for the other overloads where you might end up not being in possession of the mutex when it returns.
So along my reasoning, I would like to indicate in my multi-threaded code that I have made a choice to ignore the return:
Mutex mtx = new Mutex();
(void)mtx.WaitOne();
Since the return value never can be anything but true.
With C# 7.0 onward you can indicate purposely ignored return values with the discard operator '_'.
int SomeOperation()
{
return report_id;
}
int main()
{
_ = SomeOperation();
}
For more information you can have a look at the Microsoft docs here.
If you want to indicate to other developers and make it crystal clear that the return value is intentionally ignored, just comment it.
SomeMethod(); // return value ignored - $REASON
I can only think of one situation, when a "return value" is not allowed to be ignored in C#: when an error occurred. This should be provided by throwing an exception, which makes it impossible to be ignored.
In other cases, it is (or better: must be) completely safe and not smelly at all to ignore return values.
I still can't see the point. Why should this improve the code? You specify to ignore the return value by purpose by not assigning it to a variable.
If you don't need this value in your code, everything is fine.
If you need it, you won't be able to write your code.
If there is a special case which must be handled and must never be implicitly ignored, an exception should be thrown.
If the called method did not have a return value and gets one later, it must be designed to not break existing code which ignores it. The existing calling code does not change.
Did I forget a case?
The Microsoft C# compiler doesn't generate a warning on ignoring returns. It doesn't need to since there is a garbage collector so there won't be any memory leakage because of ignoring returned objects (unless they are IDisposable of course). Hence, there's no need to explicitly "override" the compiler.
EDIT: Also, I believe "maintainability" issue is more like a documentation and naming practice issue. I understand that this was only an example, but you wouldn't expect a method called SomeOperation to return a ReportId. You would, however, expect a GetReportId method to return a ReportId without having a lot of side effects. Indeed, ignoring the return value of a method called GetReportId would be rather strange. So, make sure that you name your methods well and people won't have doubts about the effects of your function calls.
EDIT 2: In this example of mutexes, I believe that the right usage would be actually not ignoring the return value. Even if the current implementation will never return false, I think it's good practice to still check the return value, just in case you will end up using another implementation in the future or they change the behaviour in a future release of the .NET Framework or something:
if (mutex.WaitOne())
{
// Your code here
}
else
{
// Optionally, some error handling here
}
object dummy = JustDontCare();
No standard conventions I'm aware of.
But I'm struggling to find a good reason for needing this. It sounds like SomeOperation() should really be two separate methods. Have you got an example of a method which really should behave this way? Why should a method bother returning a result if it's going to be ignored?
Sometimes it's useful to be able to put in (void) to indicate to a future coder looking at the code that you know perfectly well it returns something, and you are deliberately ignoring it.
That said, the C# compiler will error on the syntax.
I've seen:
var notUsed = SomeOperation();
Not so fond of it though.
The convention in .Net is, if you don't store or use a return value that means you ignore it implicitly, there's no explicit convention, and the API is generally designed so return values can be generally ignored, with the exception of boolean values representing fail, success state.
But even in the case of Boolean return values representing success/fail status, the convention is that if you ignore the return value (don't use it) that means the code doesn't depend on the success status of previous call.
Is it true that the only way to handle default function arguments is through function overloading?
For example, in PHP I can do this:
function foo($x, $y=0)
{
}
Would the best way to handle it in C# be this?
void foo(int x)
{
foo(x, 0);
}
void foo(int x, int y)
{
}
Example lifted from here
Edit
Made the C# example into actual C# (Thanks Blair Conrad)
Just to satisfy some curiosity:
From Why doesn't C# support default parameters?:
In languages such as C++, a default value can be included as part of the method declaration:
void Process(Employee employee, bool bonus = false)
This method can be called either with:
a.Process(employee, true);
or
a.Process(employee);
in the second case, the parameter bonus is set to false.
C# doesn't have this feature.
One reason we don't have this feature is related to a specific implementation of the feature. In the C++ world, when the user writes:
a.Process(employee);
the compiler generates
a.process(employee, false);
In other words, the compiler takes the default value that is specified in the method prototype and puts it into the method call - it's just as if the user wrote 'false' as the second parameter. There's no way to change that default value without forcing the user of the class to recompile, which is unfortunate.
The overloading model works better in this respect. The framework author just defines two separate methods, and the single-parameter one calls the two-parameter method. This keeps the default value in the framework, where it can be modified if necessary.
It would be possible for a compiler to take something like the C++ definition and produce the overloads, but there are a few issues with that approach.
The first one is that the correlation between the code that the user writes and the code the compiler generates is less obvious. We generally try to limit magic when possible, as it makes it harder for programmers. The second issue has to do with things like XML doc comments and intellisense. The compiler would have to have special rules for how it generates doc comments for the overloaded methods, and intellisense would need to have smarts to collapse the overloaded methods into a single method.
Writing overloads yourself is a bit less convenient, but we think it's an acceptable solution.
Yes, that'd be best, except you'd omit the $s on the parameter names, as others have pointed out. For those interested in the rationale behind the lack of default parameter values, see #Giovanni Galbo's explanation.
Regarding the excerpt from the c# faq:
Most of the problems listed there were solved for VB.Net (specifically the intellisense and xml comments issues), meaning they're really red herrings-- there is code available to the C# team that will solve the problem.
Another reason has to do with forcing a user of a class to re-compile, but that's a bit of a red herring, too. If you change a default value in your framework class and the user does not have to recompile, you risk the user not knowing that the default value changed. Now you have a potential bug in the code that doesn't show up until runtime. In other words, the alternative of overloading the function is at least as bad. Of course, this also presumes a specific implementation of the feature, but it's the implementation suggested in the faq.
Therefore you have to weigh the remaining reason ("try to limit the magic") vs the fact (which they acknowledge) that writing the overloads is "a bit less convenient". Personally, I say put the feature in, and let the programmer decide whether or not to use it.
Default arguments are part of C++, but as of C# 3.5 default arguments are still not supported-- you'll have to overload. They've been available in VB.Net since 1.0.
Yes.
Or currying.
Or abstracting into a class and using default values there.
No, AFAIK C# does not support overriding, and yes, that is the recommended way of accomplishing the same effect.
As pointed out, this isn't currently available in C# however they will be present within C# 4.0 as Sam Ng discusses on his blog:
http://blogs.msdn.com/samng/archive/2009/02/03/named-arguments-optional-arguments-and-default-values.aspx
doe this not do the job?
void foo(int x):this(x, 0){}
void foo(int x, int y){
// code here
}