The "Enum as immutable rich-object": is this an anti-pattern? - c#

I've often seen and used enums with attached attributes to do some basic things such as providing a display name or description:
public enum Movement {
[DisplayName("Turned Right")]
TurnedRight,
[DisplayName("Turned Left")]
[Description("Execute 90 degree turn to the left")]
TurnedLeft,
// ...
}
And have had a set of extension methods to support the attributes:
public static string GetDisplayName(this Movement movement) { ... }
public static Movement GetNextTurn(this Movement movement, ...) { ... }
Following this pattern, additional existing or custom attributes could be applied to the fields to do other things. It is almost as if the enum can work as the simple enumerated value type it is and as a more rich immutable value object with a number of fields:
public class Movement
{
public int Value { get; set; } // i.e. the type backing the enum
public string DisplayName { get; set; }
public string Description { get; set; }
public Movement GetNextTurn(...) { ... }
// ...
}
In this way, it can "travel" as a simple field during serialization, be quickly compared, etc. yet behavior can be "internalized" (ala OOP).
That said, I recognize this may be considered an anti-pattern. At the same time part of me considers this useful enough that the anti might be too strict.

I would consider this to be a poor pattern in C# simply because the language support for declaring and accessing attributes is so crippled; they aren't meant to be stores of very much data. It's a pain to declare attributes with non-trivial values, and it's a pain to get the value of an attribute. As soon as you want something remotely interesting associated with your enum (like a method that computes something on the enum, or an attribute that contains a non-primitive data type) you either need to refactor it to a class or put the other thing in some out-of-band place.
It's not really any more difficult to make an immutable class with some static instances holding the same information, and in my opinion, it's more idiomatic.

I'd say it's an anti-pattern. Here's why. Let's take your existing enum (stripping attributes for brevity here):
public enum Movement
{
TurnedRight,
TurnedLeft,
Stopped,
Started
}
Now, let's say the need expands to be something a little more precise; say, a change in heading and/or velocity, turning one "field" in your "pseudo-class" into two:
public sealed class Movement
{
double HeadingDelta { get; private set; }
double VelocityDelta { get; private set; }
// other methods here
}
So, you have a codified enum that now has to be transformed into an immutable class because you're now tracking two orthogonal (but still immutable) properties that really do belong together in the same interface. Any code that you'd written against your "rich enum" now has to be gutted and reworked significantly; whereas, if you'd started with it as a class, you'd likely have less work to do.
You have to ask how the code is going to be maintained over time, and if the rich enum is going to be more maintainable than the class. My bet is that it wouldn't be more maintainable. Also, as mquander pointed out, the class-based approach is more idiomatic in C#.
Something else to consider, as well. If the object is immutable and is a struct rather than a class, you get the same pass-by-value semantics and negligible differences in the serialization size and the runtime size of the object as you would with the enum.

Related

How to fill a random object with random data at runtime

I want to create a little testing tool for my program, which fills all properties of a random object (unknown type at compile time). A sample structure:
public class HeadObject
{
public Company Company { get; set; }
public CompanyAddress CompanyAddress { get; set; }
public List<Details> Details{ get; set; }
public ApplicationUser AppUser { get; set; }
}
and e.g the class Company would look like this:
public class Company
{
public string CompanyName{ get; set; }
public string PhoneNumber{ get; set; }
public Address Adress{ get; set; }
public int CompanyNo{ get; set; }
public List<Employee> Employees{ get; set; }
}
its pretty simplified because in each HeadOjbect there are around 30 properties which may contain sub properties or a property can be a list etc.. I need to populate ~30 HeadObjects at runtime. I already tried it with different libraries like GenFu, nBuilder or Bogus.
The last 2 have the problem that I have to fill the properties by myself only the data is generated. GenFu looks like it can only deal with primitive properties like int, string, ... And if you imagine the HeadObject as a root of a tree, then there would be
~ 300 Nodes per tree
Height of a tree: between 1 and 7(!)
~30 Different trees (HeadObjects)
so it would take days to write this all down by myself and maintenance would be a pain.
I appreciate any kind of idea.
UPDATE
Thanks for your replies! How can I initialize the objects? e.g I get the Company property of my head object and then I want to initialize it to be able to fill it. My method (its recursive) starts like this:
private static T FillAllProperties<T>(T masterObject) where T : new()
{
try
{
Type masterType = masterObject.GetType();
T headObject = new T();
......IF primitive Type fill it and return the value
otherwise get Properties into firstProperties.......
foreach (var propertyInfo in firstProperties)
{
var objectInstance = FillAllProperties(propertyInfo.PropertyType);
headObject.GetType().GetProperty($"{propertyInfo.Name}").SetValue(headObject, objectInstance, null);
}
Now I have 2 questions:
is my way to initialize the generic type correct?
at the recursive call I get the following error :" The type 'System.Type' must have a public parameterless constructor in order to use it as parameter 'T'....
I probably need another "construction" for this algorithm, but how..?
You are going to go through deep pain...
Basically the idea is to iterate through the object's properties and randomly fill them.
You can iterate using YourObject.GetType().GetProperties() then using PropertyInfo.PropertyType to know the type.
Then with each Proprety Type you can check whether it is a simple (i.e. int, double...) structure or a more complex object (by using Type.IsPrimitive, Type.IsClass or Type.IsValueType).
If it a class, you recursively call the same method, because it means you have a complex type.
If it is a structure, then maybe you should iterate over the fields instead of the properies ?
If it is a primitive you can set its value using PropertyInfo.SetValue(), but how are you going to randomize anything ? You need to perform a switch on .Net base types then generate a value at random for each type.
By the way, a string is a class, not a primitive, so you will need to make a special case for this one.
Also, List<string> is a funny one, because it is an Enumerable object. So it is another specific case.
And if you want to have fun, try out a Dictionary, or better, Tuple...
Anyway, there is no simple way to perform this. Your simple testing tool will soon become a nightmare because of all the cases you couldn't even see from far away...
Maybe there is a better option to test your program than filling it with random values that don't have any actual meaning ?
If you do not know the properties at runtime, you will have to use Reflection. But starting with 30 properties, I would probably use it regardless (or look if I made any mistakes in my design). Writing that much manually is just too prone to mistakes.
A alternative might be to have a ISelfRandomizing interface with a SelfRandomize() function, so each type input can carry it's own randomization code. And hope people actually provide it.
Something that might be viable for your case: structs by default use reflection for comparison. What would be the equivalent of a base class for them, has reflection based fallback code. You are invited to override it, but if you do not it just "works". You could make a abstract base class that you use for all those classes. That way you only need to write the reflection code once.
As for the actual randomization: Random. A common mistake is creating new instances of Random in a loop. Do not do that. You want to keep a single Random instance around as long as possible, for optimal randomisation. I have no sensible way to transform a Integer return into a string, so the next best non-sensible thing is to create a large random number and call ToString() on it. That will give you something to put in those spots at least.

Strange line in C# camera code

My team is working on documentation for a robot project. We're currently documenting some camera code but we don't understand some lines.
public Mat Image { get; set; }
public double GyroAngle { get; set; }
Could anyone explain what these lines are doing? If the GyroAngle is simply a double why does it have { get; set; }? Thanks in advance.
It is not strange at all.
A field cannot be used in interfaces but properties can.
Most .NET binding can be done against a property. Not fields
You can change the implementation of a property and keep the contract so no dependent code breaks. For example, in the setter you may add validation. You may not have validation today, but if you do in the future, you can add that. If it was a field, and you change it to property, many bad things will happen such as binary serialization may break.
Some tools will also yell at you if you expose a field as public.
The MSDN has some useful info.
public string FirstName { get; set; } = "Jane";
The class that is shown in the previous example is mutable. Client code can change the values in objects after they are created. In complex classes that contain significant behavior (methods) as well as data, it is often necessary to have public properties. However, for small classes or structs that just encapsulate a set of values (data) and have little or no behaviors, you should either make the objects immutable by declaring the set accessor as private (immutable to consumers) or by declaring only a get accessor (immutable everywhere except the constructor). For more information, see How to: Implement a Lightweight Class with Auto-Implemented Properties.

Is it possible to shorten object names in c#?

I've looked far and wide, and haven't found a mention on what I try to do, so I'm kind of afraid it could be impossible. But I think it's worth a try.
I have an object, which is a part of a class put in another class, which is global. It looks like that:
public struct descrptiveButLongName
{ public static GameData relativelyLongName {get; set;} }
class GameData
{ public playerData notSoShortNameToo {get; set;} }
I'm referencing the descriptiveButLongName.relativelyLongName.notSoShortNameToo quite often in my code (that's basically a player object in a game), and it takes really, really large amount of space. I was trying to find a way to make some shorthand for that particular property, so I could just name it for example PlayerData. Something to the effect of:
using PlayerData = FileName.descriptiveButLongName.relativelyLongName.notSoShortNameToo;
but with aliasing an actual objects, not a type name, while still having the ability to keep descriptive names. Is this even possible in C#?
First of all there is something that is called a Law of Demeter which, shortly speaking says "Only talk to your immediate friends."
http://c2.com/cgi/wiki?LawOfDemeter
http://en.wikipedia.org/wiki/Law_of_Demeter
The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents), in accordance with the principle of "information hiding".
In your case if you would apply this principle (which I strongly recommend to), even if your property names would be long you wouldn't have this problem.
Second of all: you are right you can use "using" directives for aliasing types and namespaces but not for certain properties.
What you could though do as some kind of a workaround is to create a special property that in it's "get" accessor takes out the whole chain, but this would then break the Law Of Demeter.
You can define a property that gets this object for you:
public GameData pData
{
get { return FileName.descriptiveButLongName.relativelyLongName.notSoShortNameToo; }
}
While aliasing like this is not possible in C#, why not make your own life easier by making shortcut properties for it yourself?
class FileName {
public GameData notSoShortName {
get {
return this.descriptiveButLongName.relativeLongName.notSoShortName;
}
}
}
Life is a convenience if you make it so... the compiler will just optimize it all away into the same code anyway, so there's not even a performance penalty.

Data encapsulation in C# using properties

currently I am thinking about data encapsulation in C# and I am a little bit confused.
Years ago, when I started to learn programing with C++, my professor told me:
- "Create a class and hide it data members, so it can't be manipulated directly from outside"
Example:
You are parsing an XML file and store the parsed data into some data members inside the parser class.
Now, when I am looking at C#. You have there properties. This feature makes the internal state / internal data of a class visible to outside.
There is no encapsulation anymore. Right?
private string _mystring;
public string MyString
{
get {return _mystring;}
set {_mystring = value;}
}
From my point of view there is no difference between making data members public or having public properties, which have getters and setters, where you pass your private data members through.
Can someone explaing me that please?
Thanks
The private data is encapsulated by the property itself. The only way to access the data is through the property.
In your situation above, there is little reason to use the property. However, if you later need to add some validation, you can, without breaking the API, ie::
private string _mystring;
public string MyString
{
get {return _mystring;}
set
{
if (IsAcceptableInput(value))
_mystring = value;
}
}
Remember that a Property, in .NET, is really just a cleaner syntax for 2 methods - one method for the property get section, and one for the property set section. It provides all of the same encapsulation as a pair of methods in C++, but a (arguably) nicer syntax for usage.
Well so properties aren't the wild west you are taking them to be at a first glance. The unfortunate truth of OOP is that a lot of your methods are getters and setters, and properties are just a way to make this easier to write. Also you control what you'd like the property to allow someone to do. You can make a property readable but not writable, like so:
private string _mystring;
public string MyString
{
get {return _mystring;}
}
Or as mentioned by Reed you can have your set method do a transformation or checking of any amount of complexity. For instance something like
private long myPrime;
public long Prime {
get { return myPrime; }
set {
if (prime(value) {
myPrime = prime;
}
else {
//throw an error or do nothing
}
}
}
You generally have all the value you get from encapsulation, with some syntactic sugar to make some common tasks easier. You can do the same thing properties do in other languages, it just looks different.
The benefit of properties is that later on, you could decide to add validation etc to the setter method, or make the getter method do some calculation or caching, and none of the code that already calls your property would need to change - since the class' interface remained stable
There still is data encapsulation, if you need it to be. Encapsulating data is not about hiding it from the client of the class or making it unaccessible, it's about ensuring a consistent interface and internal object state.
Let's say you have an object representing a stick shift car, and a property to set the speed. You probably know that you should shift gears in between speed intervals, so that's where encapsulation comes in.
Instead of simply making the property public, thus allowing public access without any verification, you can use property getters and setters in C#:
class StickShiftCar : Car
{
public int MilesPerHour
{
get {return this._milesPerHour;}
set
{
if (vaule < 20)
this._gearPosition = 1;
else if (value > 30)
this._gearPosition = 2;
...
...
this._milesPerHour = value;
}
}
While this example is not necessarily compilable, I am sure you catch my drift.
You may be missing the fact that you don't have to have properties to correspond to all class member fields. You can decide which properties to add to your class, and whether or not they will be accessible outside of the class.
Looking a bit deeper, why did your professor tell you to encapsulate? Just because it is the proper object-oriented design? Why is that the proper way? Programming languages and paradigms are just a way of coping with the complexity of getting a processor to run our code in an understandable way. There are two readers of code, the machine and humans. The machine will happily load data from, or branch to, any address in the memory space. We humans on the other hand like to think of "things". Our brains deal with "things" that have attributes or that perform actions. A lion will eat you, a spear can defend you, a lion is furry, a spear is pointy. So we can understand programs if they are modeled as "things". Properties are supposed to model the attributes of a thing, and methods are supposed to model the things actions. In practice it can become quite fuzzy and everything cannot be modeled as a real world action, but the effort to do so, when done well, can make a program understandable.
The very first attempt of using property to encapsulate the value is get;set;
But C# provide more advanced feature to enrich functions inside get and set to make the property read-only, write-only or with certain conditions.
For example, to set the value as
private string temp;
public string temp
{
get
{
return temp;
}
}
will be better than using:
public readonly string Temp;

C#: Can I remove "{ get; set; }"?

Is there a difference between:
public T RequestedValue { get; set; }
and
public T RequestedValue;
?
Taken from this code:
public class PropertyChangeRequestEventArgs<T>:EventArgs
{
public PropertyChangeRequestEventArgs(T pRequestedValue)
{
RequestedValue = pRequestedValue;
}
public T RequestedValue { get; set; }
}
The first is an Auto-Implemented Property the second is a Field. Regular Properties expose Getters and Setters but have a private field to actually store the value:
private int someProperty;
public int SomeProperty
{
get { return someProperty; }
set { someProperty = value; }
}
The first allows you to change certain aspects of the implementation of your class without affecting all the other code in your application. The most important point is that, with properties, changes can be made without breaking binary compatibility (although a field can often be changed to a property without breaking code). If it is a public member, a property is advisable. (Stealing shamelessly from Snarfblam's comment)
From the Properties page:
Properties are members that provide a flexible mechanism to read, write, or compute the values of private fields. Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods.
Properties with a backing field are the most flexible form as they allow easy implementation of things like the INotifyPropertyChanged event for updating the UI in Model-View-ViewModel implementations.
deep explanation!
The {get; set;} is an automatic property, while the second is a field.
a field is a normal variable, from some type, that contains data.
a property is a couple of methods (well sometimes it's just one), one for get, and one for set. they only have a syntax like fields, but actually they are quite different.
properties are usually for filtering the set of the value, or virtualizing something in the get, etc.
automatic properties, also create a private field behind the scenes, return its value in the get, and set its value in the set.
seemingly this is just like a normal field, but behind the scenes (IL) using properties is totally different from using fields.
a.Property1 = 4;
is translate into something like:
a.Set_Propert1(4);
and this:
x = a.Property1;
is translate to something like this:
x = a.Get_Property1();
so why is it a good practice to use only public properties, even if they are automatic?
say you are writing a library, that is used by other application, and someday you want to release a new version of that library that constrains one of your class' fields..
if you are using properties, you can just change the property (even if it is an automatic one, you can replace it by a full one), and then any application which used your library can still use it in the same way.
but if you made a public field, which you now want to constrain, you'll need to make a property for this and make the field private, but if you will, any application that used you library will no more be bale to, because the way it use fields and property is different.
You may write:
public T RequestedValue { get; set; }
as a shortcut of:
private T _requestedValue;
public T RequestedValue
{
get { return this._requestedValue; }
set { this._requestedValue = value; }
}
They are totally equivalent, also considering the performance.
The answer is, yes you can remove the { get; set; } but then a whole load subtle differences kick in. Some will say fields and properties express radically different design intent but in practice this distinction has been eroded over the years as C# evolves and progressively blurs the the syntactic differences.
For a good list of compiler-binary level differences between fields and properties refer to SO question difference-between-property-and-field-in-c. But the answers to that question missed one significant point about the special role of properties when declaring interfaces.

Categories

Resources