Reputation: 30295
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
Upvotes: 17
Views: 8069
Reputation: 107327
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"; // <-- Username 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 ""
Upvotes: 8
Reputation: 6427
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
Upvotes: 5