C
C#12mo ago
Jibz

getting warning: CS8618 - Non-nullable variable must contain a non-null value when exiting construct

I guess, it's not a big deal since the code is getting compiled but I still want to understand why I'm getting this warning and how can I resolve this. I was using a generic struct
truct Rectangle<T>
{
T length;
T width;

public T Length{
readonly get{ return length; }
set{ length = value; }
}
public T Width{
readonly get{ return width; }
set{ width = value; }
}

public Rectangle(T L, T W) // <-- this is where I am getting the warning
{
Length = L;
Width = W;
}
}
truct Rectangle<T>
{
T length;
T width;

public T Length{
readonly get{ return length; }
set{ length = value; }
}
public T Width{
readonly get{ return width; }
set{ width = value; }
}

public Rectangle(T L, T W) // <-- this is where I am getting the warning
{
Length = L;
Width = W;
}
}
29 Replies
ero
ero12mo ago
With the code you've provided, what's stopping me from creating a Rectangle<Rectangle<List<Rectangle<StringBuilder>>>>?
Jibz
Jibz12mo ago
sanity?
ero
ero12mo ago
So nothing, basically That's the issue you're having I can pass any nullable class as T
Thinker
Thinker12mo ago
The actual error occurs because the compiler can't tell that Length and Width aren't null if their corresponding fields aren't null.
ero
ero12mo ago
This is obviously a glaring issue, and is if I do pass a nullable type, then it's your responsibility to make sure length and width are not null when the constructor exits
Thinker
Thinker12mo ago
What you can do is either ignore the warning because it doesn't really matter in this case, or add [NotNullWhenNotNull(nameof(length))] to Length, and the same for Width.
Jibz
Jibz12mo ago
so what can I do to stop you?
ero
ero12mo ago
This is because you explicitly specified those two to be non-null
Thinker
Thinker12mo ago
Maybe constraint T to INumber<T> if Ero thinks that's more sane
ero
ero12mo ago
Yup, exactly that
Jibz
Jibz12mo ago
INumber?
ero
ero12mo ago
You may also consider using auto-properies for Length and Width You may also consider renaming Length to Height
Thinker
Thinker12mo ago
Basically so that T can only be a number, because using string for length and height doesn't really make sense.
ero
ero12mo ago
public readonly record struct Rectangle<TUnit>(
TUnit Width,
TUnit Height) where TUnit : INumber<TUnit>;
public readonly record struct Rectangle<TUnit>(
TUnit Width,
TUnit Height) where TUnit : INumber<TUnit>;
Should get you where you want
Thinker
Thinker12mo ago
or
struct Rectangle<T> where T : INumber<T>
{
public T Length { get; set; }
public T Width { get; set; }

public Rectangle(T length, T width)
{
Length = length;
Width = width;
}
}
struct Rectangle<T> where T : INumber<T>
{
public T Length { get; set; }
public T Width { get; set; }

public Rectangle(T length, T width)
{
Length = length;
Width = width;
}
}
(if you prefer the full type over a record) Although the record will also give you equality methods, which might be something you want
Jibz
Jibz12mo ago
The type or namespace name 'INumber<>' could not be found
ero
ero12mo ago
Is anyone surprised Can you tell us what type of project you're making?
Thinker
Thinker12mo ago
INumber is in System.Numerics so you'll have to import that
ero
ero12mo ago
What tutorial are you following? Do you know what .net version your project is using?
Jibz
Jibz12mo ago
Yeah dotnet 7
ero
ero12mo ago
Ah, that's good then Importing System.Numerics should do it
Jibz
Jibz12mo ago
well.. this is frustrating. I'm using INumber as struct Rectangle <T> where T : INumber<T> but the warning doesn't go away 😓
ero
ero12mo ago
Try where T : unmanaged, INumber<T> Might need to turn them around I wonder if it's possible to just constrain it to notnull instead of unmanaged Though I think unmanaged is a better fit
Thinker
Thinker12mo ago
yeah that has nothing to do with the INumber<T> thing at all again this is the actual issue
Jibz
Jibz12mo ago
right, so this error can't be removed?
Thinker
Thinker12mo ago
If you were using auto-properties then it would go away That's the easiest way
Jibz
Jibz12mo ago
nvm. Yeah, its gone! thanks both of you!
Thinker
Thinker12mo ago
catok
Accord
Accord12mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.