Using nullable types in C# - c#

I'm just interested in people's opinions. When using nullable types in C# what is the best practice way to test for null:
bool isNull = (i == null);
or
bool isNull = !i.HasValue;
Also when assigning to a non-null type is this:
long? i = 1;
long j = (long)i;
better than:
long? i = 1;
long j = i.Value;

I would use this:
long? i = 1;
...some code...
long j = i ?? 0;
That means, if i is null, than 0 will be assigned.

Use the forms that were specially implemented for you by the C# team. If anyone objects, tell them Anders said it was okay.
What I'm saying, flippantly, is that a lot of work went into integrating nullable types into c# to give you a good programming experience.
Note that in terms of performance, both forms compile down to the same IL, ie:
int? i = 1;
bool isINull = i == null;
int j = (int)i;
Ends up like this after the C# compiler has got to it:
int? i = 1;
bool isINull = !i.HasValue;
int j = i.Value;

I would always use the (i==null) form. It expresses what you are doing.
WRT the second question, I think either form is fine. However I'd always check it against null first and take appropriate action - perhaps wrapping that check and action up in a helper method (often it just sets a default value).

I haven't used Nullable Types in practice, but for the second, I'd actually suggest using j.GetValueOrDefault(). The documentation suggests that the latter would actually throw an InvalidOperationException in the event of a null value. Depending on the internal implementation of the explict cast operator for long?, the former might, too. I'd stick with GetValueOrDefault and treat the null/default case appropriately.

I tend to use the first on both, because as it needs to be supported later in its life-cycle, these seem easier to understand what the intent of the original writer.

Opened up Reflector. HasValue is a lookup on a boolean flag which is set when the value is changed. So in terms of cycles a lookup is going to be faster then compare.
public Nullable(T value)
{
this.value = value;
this.hasValue = true;
}
private bool hasValue;
internal T value;
public bool HasValue
{
get
{
return this.hasValue;
}
}

They're both the same, but I would use the former version on both, since it's more common in the language: comparison to null and casting to a type.

I usually tend to lean towards the first option in both scenarios, since it's more 'primitive' oriented opposed to object oriented (which was really what we were going for), but it really doesn't matter that much

Related

Nullable vs. Out Parameter when checking for valid/existent values

I have two questions and I'd like some help with them, please.
I have client code that needs to access to a variable/value that is changing over time, in fact, it is calculated on retrieval, and it is retrieved by many methods several times over runtime, however, it's calculation is not always possible as the requirements for it are not always present, in such cases, a false or null is returned and the client checks this to decide wether to proceed. Now, I have two approaches, the first one, A, is my classic one, B however, looks good to me as well.
A) I have this method with an out parameter similar to the TryParse methods on some C# libraries:
public bool GetLeadingTrailSegment(out Vector3 lastTrailSegment)
{
if (_line.positionCount > 1)
{
lastTrailSegment = lead - _line.GetPosition(_line.positionCount - 2);
return true;
}
lastTrailSegment = Vector3.zero;
return false;
}
B) I have this nullable property which tries to do the same job as the above code:
public Vector3? leadingTrailSegment
{
get
{
if (_line.positionCount > 1)
{
return lead - _line.GetPosition(_line.positionCount - 2);
}
return null;
}
}
The client code is as follows:
A) Here the bool tells the client code wether the value is safe(useful?) to use.
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
Vector3 leadingTrailSegment;
if (pointer.GetLeadingTrailSegment(out leadingTrailSegment))
{
return !midline.ParallelTo(leadingTrailSegment);
}
return true;
}
B) Here, the fact of the HasValue property of the nullable being false tells the client wether it is safe:
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
Vector3? leadingTrailSegment = pointer.leadingTrailSegment;
if (leadingTrailSegment.HasValue)
{
return !midline.ParallelTo(leadingTrailSegment.Value);
}
return true;
}
First question: Of these two approaches, which one is best or what are the pros/cons between or flaws within them?
Second question: I used to have the client B approach written as:
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
if (pointer.leadingTrailSegment.HasValue)
{
return !midline.ParallelTo(pointer.leadingTrailSegment.Value);
}
return true;
}
This was wrong, right? Because the Value property of the nullable may have changed by the second call.
I like best the out parameter approach, you can use the result in the if clause, and the variable can even be declared inline in other versions of C# but I'd really like to give a shot to nullables and make them useful in situations like these (and not only when I look for an unassigned value, which are the cases I use them in). I hope someone can give their thoughts on this.
Thanks.
I would much prefer a call returning a null than using output parameters. Output parameters are a kind of "side-effect" prone code constructs that I personally really dislike. It means the calling code has to define a variable before use, and it introduces weak points where it would be easy to induce a bug if you put in the wrong variable in the call by accident. It also prevents you from using the code in a call chain with the null-conditional and null-coalescing operators. You cannot do something like var v = GetLeadingTrailSegment() ?? new Vector3();.
The second point of interest is the use of a Nullable. If the Vector3 type is a value type, then that is fine and makes sense. If it is a reference type (pretty much everything other than integral types and structures in .NET), there is no need for it. Just return null; and if (variable != null) { ... }. The case for returning a bool is usually when you have return value clashes. For example if null was returned as a valid value in itself, and you needed a way to differentiate between a valid null or an invalid response. This does not appear to be the case here.
My two cents :)
tldr:
I would rather ask why you want to have a method that returns a boolean but the name suggest another thing.
If I have player.GetCurrentHp() and the method returns false if the player has no hp or hp == 0, I would fell that the name is misleading and I would prefer have a player.isAlive() method.
Is not something wrong per se from a logic or software perspective, but I will not help the next developer to work with that code, or yourself in 6 months.
In your case I would go with two methods for LayoutPointer;
public bool IsValid() // <--- I like when boolean methods represent 'is, can, have' actions, ideas, or properties.
{
return _line.positionCount > 1;
}
and
public bool GetLeadingTrailSegment()
{
if (!IsValid())
{
return Vector3.zero;
}
return (lead - _line.GetPosition(_line.positionCount - 2));
}
And then;
public bool IsDrawingOverAllowed(LayoutPointer pointer)
{
if (pointer == null)
{
Debug.LogWarning("IsDrawingOverAllowed: Pointer is null!");
return true; // or false, it depends on your design..
}
if (!pointer.IsValid()) // <-- I also like early returns :D
{
return true;
}
var leadingTrailSegment = pointer.GetLeadingTrailSegment()
return !midline.IsParallelTo(leadingTrailSegment);
}
I know that can be more 'verbose' but remember the idea that create code for machines is easy, but code for humans is harder.. At the end you want to have some code easy to read, understand and maintain.
Side Note; Yes, I know that sometimes can be useful, like in Physics.Raycast but if you are not implementing the TryParse pattern (if you want for example avoid the use of try/catch) I cannot see much gain trying to have just one method that does two things.

Boolean to integer conversion

Is there a way to covert from bool to integer without a conditional statement (e.g., if-statement)?
int intValue = boolValue ? 1 : 0;
No, there is not. You may hide this conditional behind additional method calls like Convert.ToInt, or prefer a different syntax like an actual if but in the end, somewhere, there will be your conditional.
int intValue = Convert.ToInt32(boolValue));
Use Convert.ToInt32(boolValue)
Despite the fact that nvoigt's answer is perfectly correct I can give you a few more examples JUST FOR FUN
NEVER! NEVER USE THIS CODE! IT IS PROVIDED JUST FOR FUN OR TO RESOLVE A DISPUTE WITH A (GOOD) FRIEND!)
At first method GetHashCode does the magic (as an implementation detail):
bool b = true;
int i = b.GetHashCode();
If you want some more esoteric approach.. hm.. you're welcome):
bool b = true;
int i = ~(b.ToString()[0] / 2) & 1;
REMEMBER! NEVER!

"Use of unassigned variable" -- work arounds?

Now I've long known and been use to this behavior in C#, and in general, I like it. But sometimes the compiler just isn't smart enough.
I have a small piece of code where right now my workaround isn't a big problem, but it could be in similar cases.
bool gap=false;
DateTime start; // = new DateTime();
for (int i = 0; i < totaldays; i++)
{
if (gap)
{
if (list[i])
{
var whgap = new WorkHistoryGap();
whgap.From = start; //unassigned variable error
whgap.To = dtFrom.AddDays(i);
return whgap;
}
}
else
{
gap = true;
start = dtFrom.AddDays(i);
}
}
The problem I'm seeing is what if you had to do this with a non-nullable struct that didn't have a default constructor? Would there be anyway to workaround this if start wasn't a simple DateTime object?
sometimes the compiler just isn't smart enough
The problem you want the compiler to solve is equivalent to the Halting Problem. Since that problem is provably not solvable by computer programs, we make only a minimal attempt to solve it. We don't do anything particularly sophisticated. You're just going to have to live with it.
For more information on why program analysis is equivalent to the Halting Problem, see my article on the subject of deducing whether the end point of a method is reachable. This is essentially the same problem as determining if a variable is definitely assigned; the analysis is very similar.
http://blogs.msdn.com/b/ericlippert/archive/2011/02/24/never-say-never-part-two.aspx
what if you had to do this with a non-nullable struct that didn't have a default constructor?
There is no such animal. All structs, nullable or otherwise, have a default constructor.
Would there be anyway to workaround this if start wasn't a simple DateTime object?
The expression default(T) gives you the default value for any type T. You can always say
Foo f = default(Foo);
and have a legal assignment. If Foo is a value type then it calls the default constructor, which always exists. If it is a reference type then you get null.
The compiler has no way of knowing that you are guaranteed to set DateTime because of your gap variable.
Just use
DateTime start = DateTime.Now;
and be done with it.
Edit Better yet, on second glance through your code, use
DateTime start = dtFrom;
There is no such thing as a default constructor in a struct. Try it:
struct MyStruct {
public MyStruct() {
// doesn't work
}
}
You can have a static constructor, but you cannot define a default constructor for a struct. That's why there's the static method Create on so many structures, and why you can say new Point() instead of Point.Empty.
The "default constructor" of any struct always initializes all of its fields to their default values. The Empty static field of certian types is for convenience. It actually makes zero difference in performance because they're value types.
Looks to me like your bool gap and the DateTime start are really the same thing. Try refactoring like this:
DateTime? gapStart = null ;
for (int i = 0; i < totaldays; i++)
{
if ( gapStart.HasValue )
{
if (list[i])
{
var whgap = new WorkHistoryGap();
whgap.From = gapStart.Value ; //unassigned variable error
whgap.To = dtFrom.AddDays(i);
return whgap;
}
}
else
{
gapStart = dtFrom.AddDays(i);
}
}
[edited to note: please post code samples that will...oh...actually compile. It makes it easier.]
[further edited to note: you set gap to true and set your start value the first time through the loop. Further refactor to something like this:]
DateTime gapStart = dtFrom.AddDays( 0 );
for ( int i = 1 ; i < totaldays ; i++ )
{
if ( list[i] )
{
var whgap = new WorkHistoryGap();
whgap.From = gapStart.Value; //unassigned variable error
whgap.To = dtFrom.AddDays( i );
return whgap;
}
}
Why are you trying to work around the design of the language? Even if the compiler could work out your entire loop in advance, which seems needlessly complex on the part of the compiler, how does it know that exceptions cannot be thrown in portions of your code? You MUST assign a value to start because you use it later in the code, possibly before its (according to you) inevitable assignment.

Which one is better to use and why in c#

Which one is better to use?
int xyz = 0;
OR
int xyz= default(int);
int xyz = 0;
Why make people think more than necessary? default is useful with generic code, but here it doesn't add anything. You should also think if you're initializing it in the right place, with a meaningful value. Sometimes you see, with stack variables, code like:
int xyz = 0;
if(someCondition)
{
// ...
xyz = 1;
// ...
}
else
{
// ...
xyz = 2;
// ...
}
In such cases, you should delay initialization until you have the real value. Do:
int xyz;
if(someCondition)
{
// ...
xyz = 1;
// ...
}
else
{
// ...
xyz = 2;
// ...
}
The compiler ensures you don't use an uninitialized stack variable. In some cases, you have to use meaningless values because the compiler can't know code will never execute (due to an exception, call to Exit, etc.). This is the exception (no pun intended) to the rule.
It depends what you want to achieve.
I would prefer
int xyz = 0;
as I believe it is more readable and not confusing.
default keyword is mostly suitable for Generics.
The purpose of the default operator is to provide you with the default value for a type, but it was added primarily to allow generics to have a valid value for values declared to be of its generic type arguments.
I don't have hard evidence but I suspect the compiler will emit the same code for both in your specific case.
However, here there is a legitimate use of default:
public T Aggregate<T>(IEnumerable<T> collection, Func<T, T, T> aggregation)
{
T result = default(T);
foreach (T element in collection)
result = aggregation(result, element);
return result;
}
Without default, the above code would need some hacks in order to compile and function properly.
So use the first, set it to 0.
no performance difference between your codes. to see clearly use int xyz = 0;
Given that the emitted CIL is identical (you get
IL_0001: ldc.i4.0
IL_0002: stloc.0
in both cases), the rule is to choose the one you feel better communicates the intent of the code. Normally, questions of feeling are subjective and hard-to-decide; in this case, however, were I the code reviewer, I would have to be presented with an extremely compelling reason to accept what looks at first sight to be an entirely superfluous use of default().
int xyz = default(int);
I like this way when working with Generics bcoz it give you flexibility to get default of whatever type you are working with.
int xyz=0;
On the other hand this is easy and fast and obviously won't work in generic cases.
Both have their pros and cons..
Regards,
int xyz = 0 is moreclear, defaut is generally used with generics
the best is
int xyz;
because you can't access to uninitialized variable.

which is better, using a nullable or a boolean return+out parameter

Lets say I have a function that needs to return some integer value. but it can also fail, and I need to know when it does.
Which is the better way?
public int? DoSomethingWonderful()
or
public bool DoSomethingWonderful(out int parameter)
this is probably more of a style question, but I'm still curious which option people would take.
Edit: clarification, this code talks to a black box (lets call it a cloud. no, a black box. no, wait. cloud. yes). I dont care why it failed. I would just need to know if I have a valid value or not.
I like the nullable version better, because you can use the null coalesce operator ?? on it, e.g.:
int reallyTerrible = 0;
var mightBeWonderful = DoSomethingWonderful() ?? reallyTerrible;
It depends on how you think the calling code should look like. And therefore what your function is used for.
Generally, you should avoid out arguments. On the other hand, it could be nice to have code like this:
int parameter;
if (DoSomething(out paramameter))
{
// use parameter
}
When you have a nullable int, it would look like this:
int? result = DoSomething();
if (result != null)
{
// use result
}
This is somewhat better because you don't have an out argument, but the code that decides if the function succeeded doesn't look very obvious.
Don't forget that there is another option: use Exeptions. Only do this if the case where your function fails is really an exceptional and kind of a error-case.
try
{
// normal case
int result = DoSomething()
}
catch (SomethingFailedException ex)
{
// exceptional case
}
One advantage of the exception is that you can't just ignore it. The normal case is also straight forward to implement. If the exceptional case something you could ignore, you shouldn't use exceptions.
Edit: Forgot to mention: another advantage of an Exception is that you also can provide information why the operation failed. This information is provided by the Exception type, properties of the Exception and the message text.
Why not throw an exception?
I would follow the pattern used in some place in the .Net library like:
bool int.TryParse(string s, out value)
bool Dictionary.TryGetValue(T1 key, out T2 value)
So I would say:
public bool TryDoSomethingWonderful(out int parameter)
It really depends on what you are doing.
Is null a meaningful answer? If not, I would prefer a bool TryDoSomethingWonderful(out int) method call. This matches up with the Framework.
If, however, null is a meaningful return value, returning int? makes sense.
Unless performance is the primary concern you should return an int and throw an exception on failure.
I would use the second, because I probably need to know right away if the call succeeded, and in that case I would rather write
int x;
if( DoSomethingWonderful( out x ) )
{
SomethingElse(x);
}
than
int? x = DoSomethingWonderful();
if( x.HasValue )
{
SomethingElse(x.Value);
}
I am in favor of using an output parameter. In my opinion, this is the kind of situation for which use of an output parameters is most suited.
Yes, you can use the coalesce operator to keep your code as a one-liner if and only if you have an alternative value that you can use in the rest of your code. I often find that is not the case for me, and I would prefer to execute a different code path than I would if I was successfully able to retrieve a value.
int value;
if(DoSomethingWonderful(out value))
{
// continue on your merry way
}
else
{
// oops
Log("Unable to do something wonderful");
if (DoSomethingTerrible(out value))
{
// continue on your not-so-merry way
}
else
{
GiveUp();
}
}
Additionally, if the value that I want to retrieve is actually nullable, then using a function with an output parameter and a boolean return value is, in my opinion, the easiest way to tell the difference between "I was unsuccessful in retrieving the value" and "The value I retrieved is null". Sometimes I care about that distinction, such as in the following example:
private int? _Value;
private bool _ValueCanBeUsed = false;
public int? Value
{
get { return this._Value; }
set
{
this._Value = value;
this._ValueCanBeUsed = true;
}
}
public bool DoSomethingTerrible(out int? value)
{
if (this._ValueCanBeUsed)
{
value = this._Value;
// prevent others from using this value until it has been set again
this._ValueCanBeUsed = false;
return true;
}
else
{
value = null;
return false;
}
}
In my opinion, the only reason most people tend not to use output parameters is because they find the syntax cumbersome. However, I really feel that using output parameters is the more appropriate solution to this problem, and I found that once I got used to it I found the syntax much preferable to returning a null value.
If there's only one way it can fail, or if you'll never need to know why it failed, I'd say it's probably simpler and easier to go with the nullable return value.
Conversely, if there are multiple ways it could fail, and the calling code could want to know exactly why it failed, then go with the out parameter and return an error code instead of a bool (alternatively, you could throw an exception, but based on your question, it seems you've already decided not to throw an exception).
You should rather then use a try catch. This seems like the caller does not know what might happen?
Should we check both bool and the out, or should i check both returns null and the actual return.
Let the method do what it should, and in the case where it failed, let the caller know that it failed, and the caller hanlde as requied.
Interestingly enough, my personal opinion sways significantly based on the nature of the method. Specifically, if the method's purpose is to retrieve a single value, as opposing to "doing something".
Ex:
bool GetSerialNumber(out string serialNumber)
vs
string GetSerialNumber() // returns null on failure
The second feels more "natural" to me somehow, and likewise:
bool GetDeviceId(out int id)
vs
int? GetDeviceId() // returns null on failure`
But I admit this really falls into "coding style" territory.
Oh, and I, too, would tend to favor exception throwing:
int GetDeviceId() // throws an exception on read failure
I'm still not sold on why they'd be so wrong. Can we have a thread on that, Oren? ;-)
I dislike Microsoft's "Try" pattern in which the "out" parameter is used to return a data item. Among other things, methods coded in that fashion cannot be used in covariant interfaces. I would rather see a method coded as: T GetValue(out bool Successful) or perhaps T GetValue(out GetValueErrorEnum result); or T GetValue(out GetValueErrorInfo result); if something beyond a true/false might be needed. Since every data type has a legal default value, there's no problem with deciding what to return if the function fails. Calling code can easily say:
bool success;
var myValue = Thing.GetValue(ref success);
if (success)
.. do something using myValue
else
.. ignore myValue
It would be nice if .net and C# offered true covariant 'copy out' parameters (the caller would allocate space for the result, pass a pointer to that space to the called function, and then copy the allocated space to the passed-in variable only after the function returned).

Categories

Resources