Difference between int? i = null and int? i = 0x0 - c#

I am writing unit tests to test if my methods will work with nulls as various properties and parameters. For one of the tests I want to use the hex value for null 0x0 as null to see if the int parameter is caught or null is caught.
[Fact]
public void GetFoo_throws_exception_when_foo_has_null_id()
{
int? nullFooId = 0x0; // would this be defined as int or null?
Foo foo = new Foo
{
FooId = nullFooId.Value
};
Action action = () => _sut.GetFoo(nullFooId.Value);
action.ShouldThrow<KeyNotFoundException>();
}
I'm wondering if the nullFooId will be null or an int and why. As well, if I explicitly put _sut.GetFoo(0x0), is it up to the compiler whether to look for the null or int representation? Does it try to find the proper number of bits?

nullFooId will be 0, not null. If you want it to be null, just set it to null.
There is nothing about "finding the proper number of bits". If there are any bits (i.e. it is a number), your nullFooId will be non-null.

Per the C# grammar, 0x0 is an integer literal of type int, with a value of decimal 0.
And given that the expression 0x0 == null evaluates to false, what value do you think int? x = 0x0; will assign to x?
Further, you say
I'm wondering if the nullFooId will be null or an int and why.
which suggests a fundamental misunderstanding. Your nullFooId is of type Nullable<int>, a struct with two properties that looks [something like] the following. Note that there is compiler magic that happens under the covers, since support for this is baked into the language itself:
public struct Nullable<T> where T : struct
{
private bool hasValue ;
internal T value ;
public bool HasValue { get { return this.hasValue ; } }
public T Value
{
get
{
if (!this.hasValue) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
return this.value;
}
}
}

Related

Cast to bool nullable of null value VS default value of bool nullable

Is there any difference between those two ways to write the same thing?
int? foo = GetValueOrDefault();
var obj = new
{
//some code...,
bar = foo.HasValue ? foo > 0 : (bool?)null
}
VS
int? foo = GetValueOrDefault();
var obj = new
{
//some code...,
bar = foo.HasValue ? foo > 0 : default(bool?)
}
It is the same. A Nullable<bool> is a struct and the language specification states:
The default value of a struct is the value produced by setting all
fields to their default value (ยง15.4.5).
Since a Nullable<T> has these two fields:
private bool hasValue; // default: false
internal T value; // default value of T, with bool=false
So yes, using default(bool?) has the same effect as using (bool?)null, because (bool?)null is also a Nullable<bool> with hasValue=false(same as using new Nullable<bool>()).
Why you can assign null at all to a Nullable<T> which is a struct, so a value type? Well, that is compiler magic which is not visible in the source.

why dont nullable strings have a hasValue() method?

I have a class which contains a nullable strings, I want to make a check to see whether they stay null or somebody has set them.
simliar to strings, the class contains integers which are nullable, where i can perform this check by doing an equality comparison
with the .HasValue() method - it seems like strings dont have this?
So how do check whether it goes from null to notNull?
public class Test
{
public string? a
public string? b
public int? c
}
var oldQ = new Test(c=123)
var newQ = new Test(c=546)
bool isStilValid = newQ.c.HasValue() == oldQ.c.HasValue() //(this is not possible?)&& newQ.b.HasValue() == oldQ.b.HasValue()
why is this not possible?
HasValue property belongs to Nullable<T> struct, where T is also restricted to be a value type only. So, HasValue is exist only for value types.
Nullable reference types are implemented using type annotations, you can't use the same approach with nullable value types. To check a reference type for nullability you could use comparison with null or IsNullOrEmpty method (for strings only). So, you can rewrite your code a little bit
var oldQ = new Test() { c = 123 };
var newQ = new Test() { c = 456 };
bool isStilValid = string.IsNullOrEmpty(newQ.b) == string.IsNullOrEmpty(oldQ.b);
Or just use a regular comparison with null
bool isStilValid = (newQ.b != null) == (oldQ.b != null);
Only struct in C# have HasValue method, but you can simple create your own string extension as below and that will solve your problem.
public static class StringExtension {
public static bool HasValue(this string value)
{
return !string.IsNullOrEmpty(value);
}
}
I hope this is helpful for someone.
The equivalent comparing to null would be:
bool isStillValid = (newQ.c != null) == (oldQ.c != null) && (newQ.b != null) == (oldQ.b != null);
That's the equivalent to your original code, but I'm not sure the original code is correct...
isStillValid will be true if ALL the items being tested for null are actually null. Is that really what you intended?
That is, if newQ.c is null and oldQ.c is null and newQ.b is null and oldQ.b is null then isStillValid will be true.
The Nullable<T> type requires a type T that is a non-nullable value type for example int or double.
string typed variables are already null, so the nullable string typed variable doesn't make sense.
You need to use string.IsNullOrEmpty or simply null

Why do I get the 'Operator '!=' can not be applied to operands of type Point and <null>' in this struct implementation

I don't really know why I get this error while trying to validate the input value in the Property code here:
using ConsoleApplication4.Interfaces;
public struct Vector:IComparable
{
private Point startingPoint;
private Point endPoint;
public Point StartingPoint
{
get
{
return new Point(startingPoint);
}
set
{
if(value != null)
this.startingPoint = value;
}
}
public Point EndingPoint
{
get
{
return new Point(this.endPoint);
}
set
{
if(value != null)
this.startingPoint = value;
}
}
The error that I get is on the lines where I have if(value!=null)
struct is a value type - it cannot be "null" like a class could be. You may use a Nullable<Point> (or Point?), however.
Point is a struct and hence can't be null.
You can use Point? which is syntactic sugar for System.Nullable<Point>. Read more about nullable types at http://msdn.microsoft.com/en-us/library/1t3y8s4s(v=vs.120).aspx
If you want to compare to the default value of Point (which is not the same as null), then you can use the default keyword:
if(value != default(Point))
A struct is a value type, not a reference type. This implies, that it can never be null, especially, that its default value is not null.
Easy rule of thumb: If you need new(), it can be null. (This is a bit simplicistic, but devs knowing, when this might be wrong, most often don't need a rule of thumb)
I don't know what you are trying to achieve with your class, but it seems what you can simply write:
public struct Vector: IComparable
{
public Point StartingPoint {get; set;}
public Point EndPoint {get; set;}
// implement IComparable
}
unless you intentionally want to create a copies of points (for whatever reason)

what does symbol '?' after type name mean

I am using Eto gui framework. I saw some magic grammar in their source code;
for example:
int x;
int? x;
void func(int param);
void func(int? param);
What's different? I am confused.
and the symbol ? is hard to google.
It means they are Nullable, they can hold null values.
if you have defined:
int x;
then you can't do:
x = null; // this will be an error.
but if you have defined x as:
int? x;
then you can do:
x = null;
Nullable<T> Structure
In C# and Visual Basic, you mark a value type as nullable by using
the ? notation after the value type. For example, int? in C# or
Integer? in Visual Basic declares an integer value type that can be
assigned null.
Personally I would use http://www.SymbolHound.com for searching with symbols, look at the result here
? is just syntactic sugar, its equivalent to:
int? x is same as Nullable<int> x
structs (like int, long, etc) cannot accept null by default. So, .NET provides a generic struct named Nullable<T> that the T type-param can be from any other structs.
public struct Nullable<T> where T : struct {}
It provides a bool HasValue property that indicates whether the current Nullable<T> object has a value; and a T Value property that gets the value of the current Nullable<T> value (if HasValue == true, otherwise it will throw an InvalidOperationException):
public struct Nullable<T> where T : struct {
public bool HasValue {
get { /* true if has a value, otherwise false */ }
}
public T Value {
get {
if(!HasValue)
throw new InvalidOperationException();
return /* returns the value */
}
}
}
And finally, in answer of your question, TypeName? is a shortcut of Nullable<TypeName>.
int? --> Nullable<int>
long? --> Nullable<long>
bool? --> Nullable<bool>
// and so on
and in usage:
int a = null; // exception. structs -value types- cannot be null
int? a = null; // no problem
For example, we have a Table class that generates HTML <table> tag in a method named Write. See:
public class Table {
private readonly int? _width;
public Table() {
_width = null;
// actually, we don't need to set _width to null
// but to learning purposes we did.
}
public Table(int width) {
_width = width;
}
public void Write(OurSampleHtmlWriter writer) {
writer.Write("<table");
// We have to check if our Nullable<T> variable has value, before using it:
if(_width.HasValue)
// if _width has value, we'll write it as a html attribute in table tag
writer.WriteFormat(" style=\"width: {0}px;\">");
else
// otherwise, we just close the table tag
writer.Write(">");
writer.Write("</table>");
}
}
Usage of the above class -just as an example- is something like these:
var output = new OurSampleHtmlWriter(); // this is NOT a real class, just an example
var table1 = new Table();
table1.Write(output);
var table2 = new Table(500);
table2.Write(output);
And we will have:
// output1: <table></table>
// output2: <table style="width: 500px;"></table>

Possible to overload null-coalescing operator?

Is it possible to overload the null-coalescing operator for a class in C#?
Say for example I want to return a default value if an instance is null and return the instance if it's not. The code would look like something like this:
return instance ?? new MyClass("Default");
But what if I would like to use the null-coalescing operator to also check if the MyClass.MyValue is set?
Good question! It's not listed one way or another in the list of overloadable and non-overloadable operators and nothing's mentioned on the operator's page.
So I tried the following:
public class TestClass
{
public static TestClass operator ??(TestClass test1, TestClass test2)
{
return test1;
}
}
and I get the error "Overloadable binary operator expected". So I'd say the answer is, as of .NET 3.5, a no.
According to the ECMA-334 standard, it is not possible to overload the ?? operator.
Similarly, you cannot overload the following operators:
=
&&
||
?:
?.
checked
unchecked
new
typeof
as
is
Simple answer: No
C# design principles do not allow operator overloading that change semantics of the language. Therefore complex operators such as compound assignment, ternary operator and ... can not be overloaded.
This is rumored to be part of the next version of C#. From http://damieng.com/blog/2013/12/09/probable-c-6-0-features-illustrated
7. Monadic null checking
Removes the need to check for nulls before accessing properties or methods. Known as the Safe Navigation Operator in Groovy).
Before
if (points != null) {
var next = points.FirstOrDefault();
if (next != null && next.X != null) return next.X;
}
return -1;
After
var bestValue = points?.FirstOrDefault()?.X ?? -1;
I was trying to accomplish this with a struct I wrote that was very similar Nullable<T>. With Nullable<T> you can do something like
Nullable<Guid> id1 = null;
Guid id2 = id1 ?? Guid.NewGuid();
It has no problem implicitly converting id1 from Nullable<Guid> to a Guid despite the fact that Nullable<T> only defines an explicit conversion to type T. Doing the same thing with my own type, it gives an error
Operator '??' cannot be applied to operands of type 'MyType' and
'Guid'
So I think there's some magic built into the compiler to make a special exception for Nullable<T>. So as an alternative...
tl;dr
We can't override the ?? operator, but if you want the coalesce operator to evaluate an underlying value rather than the class (or struct in my case) itself, you could just use a method resulting in very few extra keystrokes required. With my case above it looks something like this:
public struct MyType<T>
{
private bool _hasValue;
internal T _value;
public MyType(T value)
{
this._value = value;
this._hasValue = true;
}
public T Or(T altValue)
{
if (this._hasValue)
return this._value;
else
return altValue;
}
}
Usage:
MyType<Guid> id1 = null;
Guid id2 = id1.Or(Guid.Empty);
This works well since it's a struct and id1 itself can't actually be null. For a class, an extension method could handle if the instance is null as long as the value you're trying to check is exposed:
public class MyClass
{
public MyClass(string myValue)
{
MyValue = myValue;
}
public string MyValue { get; set; }
}
public static class MyClassExtensions
{
public static string Or(this MyClass myClass, string altVal)
{
if (myClass != null && myClass.MyValue != null)
return myClass.MyValue;
else
return altVal;
}
}
Usage:
MyClass mc1 = new MyClass(null);
string requiredVal = mc1.Or("default"); //Instead of mc1 ?? "default";
If anyone is here looking for a solution, the closest example would be to do this
return instance.MyValue != null ? instance : new MyClass("Default");

Categories

Resources