why dont nullable strings have a hasValue() method?
Asked Answered
P

4

12

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?

Periclean answered 6/3, 2020 at 10:50 Comment(9)
Use s == null and s != null?Kantar
@Periclean For null check of string you can use string.IsNullOrEmpty().Enchant
i want to check whether it goes from no value to has valuePericlean
No reference types have HasValue. Only nullable value types have such a thing.Unitive
Even for nullable value types you typically do not/should not use .HasValue. Test for (in)equality with null.Massage
You always can create your own extension HasValueEnrapture
There is no such thing as string? in c# version lower than 8. Are you using c# 8?Inkle
HasValue and Value are properties, not methods so invoking .HasValue() would be wrong anywayComplicate
a string is an object and not a nullable<t>Sebastiansebastiano
I
10

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);
Irving answered 6/3, 2020 at 10:56 Comment(5)
@Complicate Technically properties are methods.Inkle
@SᴇM: Properties are not methods. Properties are implemented as a pair of methods, but that's an implementation detail. Properties and methods are both members.Seddon
@EricLippert The keyword was "Technically".Inkle
Lets explore further. Are events "technically methods"? Suppose a property getter is inlined 100% of the time into a field access. Is it "technically a method" then? I am interested to learn about your belief system.Seddon
@EricLippert I'm very touched by your interest in my "belief system", but I will not expand it here. I'm not saying properties are methods and by saying "technically" - I meant it was internally implemented as methods (setting and getting method internally cause a method call). Also, if someone thinks that I said something wrong, I'm open to discussion/correction in an "appropriate discussion way".Inkle
W
1

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.

Woodcraft answered 27/9, 2022 at 7:32 Comment(2)
fixed your typo in "struct", but also want to point out there is no such thing as "struct classes" they are either structs or classesGourde
also IMHO your method should be renamed to HasNonEmptyValue to reflect that it treats empty (a value) as falseGourde
U
0

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.

Unitive answered 6/3, 2020 at 10:58 Comment(0)
M
0

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

Mug answered 6/3, 2020 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.