I have switched to enable nullable in my project that uses C#8. Now I have the following class:
public class Request
{
public string Type { get; set; }
public string Username { get; set; }
public string Key { get; set; }
}
Compiler of course complains that it cannot guarantee that these properties won't be null. I can't see any other way of ensuring this than adding a constructor that accepts non-nullable strings.
This seems fine for a small class, but if I have 20 properties, is this the only way to list them all in a constructor? Is it possible somehow to e.g. enforce it with the initializer:
var request = new Request { Type = "Not null", Username = "Not null" }; // Get an error here that Key is null
P.S. There is a good answer that suggests using iniatlizer for properties, but that does not always work e.g. for types like e.g. Type
that one cannot just intialize to some random value
Nullable variables may either contain a valid value or they may not — in the latter case they are considered to be nil . Non-nullable variables must always contain a value and cannot be nil . In Oxygene (as in C# and Java), the default nullability of a variable is determined by its type.
Constructors are special methods in C# that are automatically called when an object of a class is created to initialize all the class data members. If there are no explicitly defined constructors in the class, the compiler creates a default constructor automatically.
Object initializer syntax is really just short-hand for explicitly assigning to fields or property setters, i.e.
var request = new Request { Type = "Not null", Username = "Not null" };
Is equivalent to:
var request = new Request(); // <-- All properties are default
request.Type = "Not null"; // <-- Type and key are default
request.Username = "Not null"; // <-- Key is still default
As you can see, the Request
instance still goes through several states where the properties are in a default status, which will be null
for reference types like string unless you assign a different default value in the constructor, as per the other answers.
Also, by specifying different default values
public string Type { get; set; } = ""
public string Username { get; set; } = "";
public string Key { get; set; } = "";
is equivalent to assigning these values in a default constructor, i.e.
public Request()
{
Type = "";
UserName = "";
Key = "";
}
As you can imagine, this is a bit wasteful if you then immediately change the value again using object initializer syntax.
As an alternative, and if you don't require a mutable class, I would suggest instead that you provide one or more constructor overloads, which then supply suitable non-null default values for any missing fields, and then make the properties immutable e.g.
public class Request
{
public Request(string type = "", string userName = "", string key = "")
{
Type = type;
Username = userName;
Key = key;
}
public string Type { get; } // <-- No setter = immutable.
public string Username { get; }
public string Key { get; }
}
You can now instantiate the class without ever going through a state where any of the properties are ever null, and without the overhead of the intermediate default assignment, e.g.
var myRequest = new Request(key: "SomeKey"); // <-- Username and Type are defaulted to ""
Initialise them in the definition
public string Type { get; set; } = ""
public string Username { get; set; } = "";
public string Key { get; set; } = "";
The object initializer syntax "new Request { }" is just syntactic sugar for new then assignment, so don't think you can get that to error in this case
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With