Problems with auto-properties - c#-3.0

This is what reflector gives:
public int Int1 { get; set; }
public string StringA { get; set; }
// Fields
[CompilerGenerated]
private int <Int1>k__BackingField;
[CompilerGenerated]
private string <StringA>k__BackingField;
The problem is that C# specification doesn't explicitly specify how backing fields for automatic properties are named.
This can be a problem for binary serialization (from book C# 3.0 in a Nutshell).
Are there any other problems with auto-properties ? Should MS specify this in C# specs ?

I don't think MS should specify a name - I think it's more reasonable to avoid binary serialization, which is always going to be somewhat brittle in my opinion. (Java serialization is similarly brittle.) If it relies on field names (and there may be a way of getting round that by attributing your properties - I'm not sufficiently experienced with binary serialization to know) then it's restricting implementation changes quite nastily already.
My biggest problem with automatic properties is that there's no way of creating genuinely readonly properties (with readonly backing fields). I've ranted about this before though...

I don't like the following about auto-properties:
It is not possible to place break points on auto-properties.
The fields in the class are obvious, you will have to examine the fields as well as the properties to know what are the fields in the class. Where if they are not used, then you can just inspect the fields region.
Removes the ability to decorate the underlying fields with readonly, volatile, etc.

Related

Correct way to define a navigation property under .NET Core 3 Entity Framework

I am very confused as I have found several different versions of how to correctly define navigation properties in Entity Framework under .NET Core 3. I found such versions as:
public List<MyObj> MyObjects {set; get;}
public List<MyObj> MyObjects {get;} = new List<MyObj>();
public virtual List<MyObj> MyObjects {set; get;}
public virtual List<MyObj> MyObjects {get;} = new List<MyObj>();
public ICollection<MyObj> MyObjects {set; get;}
public virtual ICollection<MyObj> MyObjects {set; get;}
And a few more. But which one is the most appropriate/up-to-date/correct version? According to Microsoft's documentation, the first one should be right, but I also found older articles with different writings.
There are 3 distinct differences in your examples
virtual - You need to mark your proprties virtual to allow lazy-loading. This is a design decision and not dependant on the version (EF/EF Core).
List<> vs ICollection - Personal choice on what type of "collection" you would like to use List<T> implements ICollection<T>. You could even use IEnumerable<T>
Getter with Property Initializer - This enforces non-null collections. I prefer to not use this pattern as it means a null means that I have not loaded the collection when not using lazy-loading. Otherwise I wouldn't know whether I had retrieved the collection or it was just empty.
Each of these patterns are design choices and down to you to decide what makes sense to your app/coding style.
TL:DR; Use virtual if you're going to be using lazy-loading (try to avoid it myself) and use whatever type makes sense for your code. I prefer not to auto-initialise my collections, though.
UPDATE Setter with property initialiser was actually a getter - Updated answer

Using PostCharp to dynamically generate a C# property

I hoping someone can provide some guidance as to how to solve the following challenge. I’ve done a fair amount of research but I’m not able to put all the pieces together. Thank you!
How I’d like to code my POCOs. Note that there will be many different properties each having a unique Guid "backing store" property who's name and ColumnAttribute will be a function of the SomeAspectAttribute annotation applied to the "main" property (e.g. CreatedBy).
[SomeAspectAttribute("_createdby_value")]
public User CreatedBy { get; }
I’d like the following to be generated:
[JsonIgnore]
[Column("_createdby_value")]
internal Guid _createdby_value { get; set; }
public User CreatedBy { get; set; }
So there looks to be a few things going on here. My struggle is putting it all together.
Add a property. IntroduceMember seems like it would work but I might have many of these where the original property Type and name will vary. Plus, given the need to introduce custom attribute upon this new property, I think I’m gonna need a dynamic, code-based means for creating this property.
Add custom attribute(s) to the dynamically added property.
I suspect I’ll need a TypeLevelAspect to find all my properties with the [SomeAspectAttribute] attribute (obviously with a better name) and do some CustomAttributeIntroductionAspect stuff.
Others?

MongoDb and Net Topology Suite

How can I save entities with geometric properties (like NTS) with mongo db?
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;
public class Area
{
public string Id { get; set; }
public Polygon Extent { get; set; }
}
When I try to save the object I get the
"Maximum serialization depth exceeded (does the object being serialized have a circular reference?)."
exception (NTS does have circular references in its objects). Is there a way to by pass it?
Yes, you can write a custom serializer. Such serializers are also included in the C# driver code itself, for instance in the CultureInfoSerializer (.NET Culture Infos have cyclic references, plus you only want to store the actual locale code, not all the derived information).
The source code of the CultureInfoSerializer is pretty straightforward.
For those still looking for a solution, I have created MongoDB.NetTopologySuite.Serialization package which adds support for serializing/deserializing NetTopologySuite models to BSON and back.

FxCop CA2227 warning and ReadOnlyCollection<T>

In my VS2008 SP1, .NET 3.5 SP1 project, I have different classes that contain different properties.
I use C#3.0 auto properties a lot.
Some of these properties need to be collections. Since I want to make it simple, I use ReadOnlyCollection<T> for these properties.
I don't want to use IEnumerable<T> since I want random access to the elements.
I use Code Analysis (FxCop rules) and I get the CA2227 warning.
I don't understand why does ReadOnlyCollection<T> should have a set method while it can't be changed... The set method can only do exactly what the property can do.
Example:
using System.Collections.ObjectModel;
namespace CA2227
{
public class MyClass
{
public ReadOnlyCollection<int> SomeNumbers { get; set; }
}
}
CA2227 : Microsoft.Usage : Change 'MyClass.SomeNumbers' to be read-only by removing the property setter. C:\Users...\Visual Studio 2008\Projects\CA2227\MyClass.cs 7 CA2227
A ReadOnlyCollection cannot be changed, but there's no reason why a property with a setter that is of type ReadOnlyCollection can't be changed to refer to a different ReadOnlyCollection. If you want the SomeNumbers property to be immutable, then it needs to be both of a read-only type, and also have a non-public setter.
EDIT
If you're convinced in what you want, then although FxCop is correct to warn you, you are happy with the warning. If you want to get rid of it, then include a SuppressMessage attribute at that point - as long as you also define a CODE_ANALYSIS constant in the project properties before you build, FxCop will honour that attribute and just not issue that particular warning on that particular occasion.
It's rather odd to block changes to the contents of the collection without also blocking changes to the collection itself. If you want to be able to set the collection from within your class while conserving the use of automatic properties, you could use a private setter. e.g.:
public ReadOnlyCollection<int> SomeNumbers { get; private set; }
Consider using
public class MyClass
{
public IReadOnlyList<int> SomeNumbers { get; set; }
}
ReadOnlyCollection = http://msdn.microsoft.com/en-us/library/ms132474(v=vs.110).aspx
IReadOnlyList = http://msdn.microsoft.com/en-us/library/hh192385(v=vs.110).aspx
The problem with ReadOnlyCollection, is that it still inherits from ICollection, and still has .Add, even though documentation say it will throw - http://msdn.microsoft.com/en-us/library/cc672239(v=vs.110).aspx

Is there a standard term for a class that contains just data, no logic?

I'm looking for a standard way to communicate to another programmer that a class is a essentially just a data container.
Take this simple User class for example:
class User
{
public string userName { get; set; }
public string passPhrase { get; set; }
public Role role { get; set; }
}
"That component makes use of the User class, which is just a (insert here) class."
I want to say "data model", but I think that's too broad. Classes described as data models often have logic.
Sometimes these are called DTOs - Data Transfer Objects.
POD - Plain Old Data
How about: struct ?
"Value object" is more precise in this case than is "Data Transfer Object". A value object contains just values; a Data Transfer Object additionally should implement a method for transferring that data to or from itself to or from some other entity. "Bean" is also an accepted term particularly within Java circles.
POXO - Plain Old X Object, where X is the language of your choice. Your case, seems like C#, so that's a POCO: Plain Old C# Object.
In Java a class with only properties and getters/setters for each property is called a bean or POJO (Plain Old Java Object)
Data Transfer Object more commonly referred to as a DTO.
This isn't standard, but I often attach the "Info" suffix to a class name to indicate that the class is just meant to store and transfer information. So I would change your User class to UserInfo.
UserData would work, too, as would a "don't add any methods to this damn thing" comment at the top.
Data Transfer Object may be correct, depending on the intent. It's essentially a container, but "container" is overloaded and generally refers to collection types.
Value Objects can have behavior, but if you have two independently created value objects with the same field values, and they can be treated as equivalent (e.g. the identity of the record doesn't matter), you could say that what you have is a value object. But usually Value Objects are best when immutable.
When there are a lot of Data Transfer Objects in a design, the design is sometimes pejoratively referred to as an Anemic Domain Model.
From A Gentle Introduction to Haskell
"A type like this is often called a tuple type, since it is essentially just a cartesian product of other types."
Data Object, Data Transfer Object, DTO