Can you make a global rule that `virtual` properties are automatically nullable? - c#

With how the virtual keyword interacts with EPiServer CMS's implementation of EntityFramework, where empty properties will be read as null, is there a way to define at a project-level that all virtual properties are nullable?
These properties are inherently & quietly nullable in any case, and we need to directly check if these properties are null or not when working on them in EPiServer projects. As I understand it, it makes more sense to designate that virtual implicitly means that the property is nullable than to have every single property on any CMS Page, Block, Media asset (image, video, audio, file) explicitly add ? to give that context & clarity.
The Null-state analysis itself is desired, however due to the overall quantity of properties that would need to be individually denoted as nullable, some way to effectively bulk-define propeties as nullable would be ideal.

No, but you can simply disable Null-state analysis for the code or whole project. Nullable reference types

Related

Validate a (JSON-deserialized) DTO with Nullable Reference Types

Using Non-Nullable Reference Types is great, but there seems to be no built-in support for enforcing Non-Nullability when compiling a class with nullable=enable and using something like XML or JSON deserialization. I know it's just compiler attributes that get set, but isn't there any easy way to make sure a deserialized object didn't have some (maybe nested!) properties that shouldn't be null, but are?
If you explicitly set a non-nullable reference property to null in your JSON, Newtonsoft.JSON and System.Text.Json will happily use that as a property value. I'm using Records everywhere to get around annoying initalization procedure and it works for serializing/deserializing, but it never actually enforces that deserialized properties are not null. :(
I don't want to check for null everywhere I use the properties - that's what I'm using Non-Nullable Reference Types for in the first place!
I'm thinking about writing a recursive reflection function to validate objects retrieved this way, but surely somebody must have already though of that problem?

I'm looking for a way to create new "primitive" types with additional constraints which are visible at coding time to users of the type

Suppose I have an entity in my universe of discourse called a Widget.
Suppose the Widget has an attribute called a WidgetCode. This attribute is defined (by the system of record) to be an alphanumeric value (ie, it's a string) of length exactly 8.
I might implement that in code as follows:
class Widget
{
private string _WidgetCode;
public string WidgetCode
{
get => _WidgetCode;
set
{
if (value.Length != 8) { throw new Exception("length must be 8"); }
_WidgetCode = value;
}
}
}
This is OK, but not ideal. The test in the setter will prevent the property from accepting an invalid value at runtime. But if some other developer wants to make use of my class, then the only way they can find out that the constraint exists is by looking at the implementation of the setter. Which would, of course, violate some pretty fundamental computer science 101 concepts.
In contrast we can look into the world of relational databases. In that world there is a fundamental type. "character", but I can create what is essentially a completely different type when I actually make use of it by specifying the length as part of the type. In the case of a WidgetCode, that would be a char(8). I can add other restrictions as well, in the form of check constraints.
When I do this, I have effectively created a new, more "refined" primitive type, which represents a WidgetCode, and does not represent any arbitrary string value of any arbitrary length.
More importantly, any SQL developer who needs to interact with my schema can see the constraints on my new type. They don't have to go and read separate documentation stored outside the schema. They don't have to live in ignorance of the constraint and hope that they never run afoul of some hidden constraint that they can't see while writing code. The constraint is declared in the schema, and the same thing which implements the constraint also documents it. It is impossible for the "documentation" to get out of synch with the implementation.
This idea doesn't have to be limited to strings. We might want to store a property called Percentage, and declare its domain as a real number between 0 and 1 with scale 3, such that it should not be possible to write the value 1.5 to this property. Once again in a relational schema, that could be a Percentage decimal(4,3) not null check (Percentage between 0 and 1).
Is there any mechanism in C# whereby that same kind of more refined type can be created, and where developers using that type can see the constraint at coding-time without having to go and read some external documentation, hoping that the documentation is up to date?
DataAnnotations get some of the way there, but they are clearly designed to inform users (specifically of GUIs) about a problem with an entered value at runtime. I am looking for a similar kind of tagging which provides the same information to developers making use of the type at coding time.
This question has been answered to my satisfaction through a combination of the comments by Eric Lippert and Matthew.
There is no particular built in language support, nor any particular annotation package, but one possibly functional approach may be to use T4 text templates.

How to implement Nullable properties in Realm objects (DateTime more exactly)?

The question is really simple, about how to workaround this error:
Fody/RealmWeaver: class 'X' field 'Y' is a
'System.Nullable`1' which is not yet supported.
This is for a DateTime? property. Nullable primitive types are indeed supported.
I know the Java version supports null values. This is about Realm .NET. I was wondering if there's any other way besides doing the old DateTime SomeNullableProperty & bool HasSomeNullableProperty thing.
We implement the standard optional properaties such as int? and bool? for primitives. This is briefly mentioned in our docs under optional properties
Reference types such as String can be null.
We also support the optional value type DateTimeOffset?.
See the full list in the AccessTests.cs
Your best option is to add a boolean field for every field
you want to allow nullability.

Workaround for Reflection Bug in Dotfuscator?

Greetings all,
I am calling Type.GetProperties(), but after running Dotfuscator, it is returning zero items, when it returned more than zero before.
public class Test
{
public int Number { get; set; }
public void ShowInfo()
{
Type type = this.GetType();
PropertyInfo[] props = type.GetProperties();
Console.WriteLine("type [" + type.Name + "] props count: " + props.Length);
}
}
If I exclude the "Number" property from renaming within Dotfuscator, then it works, but otherwise it doesn't. However, it is not possible for me to do this for all properties in my project, as it would lead to possible bugs.
Are there any workarounds for this method? Or even other "free" obfuscation applications I could use?
I have already tried looking on their website to submit a bug, but I am only using the community edition so there doesn't seem to be as much support for it.
Dotfuscator automatically strips properties (which are just metadata anyway - the real work is done by the get/set pair of methods that are automatically created) during renaming. It also renames the underlying get/set methods as well. Depending on what you are trying to do, you'll need to exclude either the property metadata itself, or the get/set methods (or possibly both) from renaming.
If you need to keep the property metadata intact (for example, to simply list the properties in a Type), you can instruct Dotfuscator to exclude properties from renaming by checking them in the tree view on the Renaming Exclusions tab or using a custom regex property rule. This will only exclude the property metadata - the get/set methods will still be renamed.
If you need to keep the get/set methods (because, for example, you are trying to get or set a property's value by reflection), you can instruct Dotfuscator to exclude those methods from renaming by expanding the property in the tree view and checking the get/set methods underneath, or by using a custom regex method rule.
As the process of obfuscation is not limited to renaming your class members, you can't be sure of that. That's the problem with obfuscation: You basically can't make any assumptions about your class anymore regarding the result of reflection. The only way I can think of is to not use reflection but expressions.
Have a look at this question and its answer to know, what I mean with "expressions": How to raise PropertyChanged event without using string name

Not-Null constraints in POCO Objects

I am currently writing an financial application, and we have a pretty standard customer table. It consists of many mandatory fields, and some optional like Cell/Fax etc.. I'm using NHibernate as a ORM and have all the mappings right. It already works.
I just wonder, how do I "express" in code that a field is not-null without commenting? I have the hbm.xml files that document this, but it's kinda awkward to look at them for things like this.
The other thing that comes to mind is that I don't want the repository to throw NHibernate Exceptions at my Logic, so maybe I should go the validation route in the Controller.
Still, how can I make the POCO code express that some fields can be null?
As you can see, I want to have Cellular and Fax be optional while Phone mandatory. They are all just composite mappings, so the mapping file just specifies that the single elements of each have to be not-null, but I hate to do the Person.Cellular != null check all the time to avoid having a NullReferenceException.
There are a few ways of doing this depending on your POCO behaviour and coding style.
Firstly, you could use nullable types to express that this field is nullable and it would therefore be implicit that the rest are not nullable.
Alternatively you could introduce a Phone value type as the type for the Phone property of the POCO you illustrated, implying that because it is not a primitive type it is "more important" - this would also enable you to encapsulate phone number validation within the class itself.
In my mind, to be a true POCO object, it need not worry about the underlying nullability within the database table it is persited in... it should actually have validation and value types that express its behaviour as a stand alone entity; thus before it gets to NHibernate it is already in a valid state.
Make notnull properties readonly and write to them via a public constructor. Make the default constructor protected or private.
public class DomainObject{
private string nnp;
protected DomainObject(){}
public DomainObject(string nnp){
this.nnp = nnp;
}
public string NotNullProp {get {return nnp;}}
public string NullableProp {get;set;}
}

Categories