4

I am trying to make a model class in C# in which i require object/List properties as optional property:

public class Customer
{
        [JsonProperty("Custid")]
        public string CustId { get; set; }
        [JsonProperty("CustName")]
        public string CustName { get; set; }
}
public class Store
{
        [JsonProperty("id")]
        public string Id { get; set; }
        [JsonProperty("Name")]
        public string? Name { get; set; }
        [JsonProperty("Customer")]
        public List<Customer>? Customers{ get; set; }            *//Error 1*
        [JsonProperty("OtherProperty")]
        public object? OtherProperty{ get; set; }                *//Error 2*
}

The above code is giving error as :-
Error 1: The type 'object' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable'
Error 2: The type 'List' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable'

Please Explain me the above scenario and provide me with the alternate solution.

VillageTech
  • 1,968
  • 8
  • 18
tripti sinha
  • 149
  • 1
  • 1
  • 6

3 Answers3

8

string, List and object are all reference types. Those are nullable by default. The Nullable type (e.g. int? is a shorthand for Nullable<int>) is only used for value types.

In C# 8.0, a new feature was introduced that allows for non-nullable reference types - i.e. reference types that explicitly disallow null assignment. This is an opt-in feature - you can enable it to allow you to more clearly show intent about the references. If you use this, the syntax used to define nullable reference types is the same as for nullable value types:

string nonNullableString = null; // Error
string? nullableString = null;   // Ok

Keep in mind that enabling non-nullable reference types means that all of the reference types that aren't followed by ? will be non-nullable; this might require you to make lots of changes in your application.

So there's your two choices. Either enable non-nullable reference types, and then you need to explicitly mark types that you want to have nullable, or stick with nullable reference types, and just use string instead of string? for the same result. I would encourage the use of non-nullable types by default, since it holds some promise for avoiding an entire class of very common programming mistakes.

Luaan
  • 62,244
  • 7
  • 97
  • 116
2

If you aren't using C# 8:

object? doesn't exists. object is already nullable.

List<Customer>? doesn't exists. List<Customer> is already nullable.

If you want to use nullable reference types you must update your compiler version!

Marco Salerno
  • 5,131
  • 2
  • 12
  • 32
  • Nullable reference types were introduced in C# 8. – Jon Skeet Dec 13 '19 at 08:40
  • Yes, quite possibly - but your answer doesn't even consider the possibility that they're *trying* to use nullable reference types, and just are using the wrong compiler version. `object?` *does* exist, but only in C# 8 with nullable reference types enabled. – Jon Skeet Dec 13 '19 at 08:42
  • To put it another way: if someone had tried to write `public class Foo` and got an error because they were using a C# 1 compiler, would you tell them that that's invalid syntax, or that they needed to use a newer C# compiler? – Jon Skeet Dec 13 '19 at 08:43
0

The Nullable<T> type requires that T is a non-nullable value type, for example int or DateTime. Reference types like string or List can already be null. There would be no point in allowing things like Nullable<List<T>> so it is disallowed.

mikenlanggio
  • 1,122
  • 1
  • 7
  • 27
  • Nullable reference types were introduced in C# 8. Note that `string?` is *not* equivalent to `Nullable` here - it's the same *syntax* as for nullable value types, but an entirely different approach. – Jon Skeet Dec 13 '19 at 08:41