To only have a property, you can simply write:
public int? Foo
{
get => _Foo;
set
{
if ( !_Foo.Equals(value) )
_Foo = value.HasValue ? value : throw new NoNullAllowedException();
}
}
private int? _Foo;
Or use a dedicated setter to ensure the not null at compile time as suggested by @SomeBody:
public int? Foo => _Foo;
private int? _Foo;
public void SetFoo(int value) => _Foo = value;
The majority will prefer this last option.
Also to be homogeneous:
private int? _Foo;
public int? GetFoo() => _Foo;
public void SetFoo(int value) => _Foo = value;
But if you need to create en entity, to use serialization or some streaming like JSON helpers as well as Visual Studio Designer or runtime Property Editor, or anything requiring a full real read and write property, like ORMs, the first is to be used.
Thus an instance of the class can remove the data of the field from inside, but others artifacts can't set the property to null, just see that it is null.
If child classes can do that, set the field protected.
If other classes in the assembly as well as childs in this assembly can do that, set the field internal.
If other classes in the assembly as well as childs in any assembly can do that, set the field protected internal.
Remark: initial value of _Foo is null.