Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
There has been talk of Enums in general violating Clean Code-principles, so I'm looking for people's favorite Enum anti-patterns and alternative solutions for these.
For example I've seen code like this:
switch(enumValue) {
case myEnum.Value1:
// ...
break;
case myEnum.Value2:
// ...
break;
}
It's one step better than switch-statements with magic strings, but this probably could have been solved better with a factory, a container or other pattern.
Or even old-school code like this:
if(enumValue == myEnum.Value1) {
// ...
} else if (enumValue == myEnum.Value2) {
// ...
}
What other anti-patterns and better implementations have you experienced with enums?
I think Enums are quite useful. I've written a few extensions for Enum that have added even more value to its use
First, there's the Description extension method
public static class EnumExtensions
{
public static string Description(this Enum value)
{
var entries = value.ToString().Split(ENUM_SEPERATOR_CHARACTER);
var description = new string[entries.Length];
for (var i = 0; i < entries.Length; i++)
{
var fieldInfo = value.GetType().GetField(entries[i].Trim());
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
description[i] = (attributes.Length > 0) ? attributes[0].Description : entries[i].Trim();
}
return String.Join(", ", description);
}
private const char ENUM_SEPERATOR_CHARACTER = ',';
}
This will allow me to define en enum like this:
public enum MeasurementUnitType
{
[Description("px")]
Pixels = 0,
[Description("em")]
Em = 1,
[Description("%")]
Percent = 2,
[Description("pt")]
Points = 3
}
And get the label by doing this: var myLabel = rectangle.widthunit.Description() (eliminating any need for a switch statement).
This will btw return "px" if rectangle.widthunit = MeasurementUnitType.Pixels or it will return "px,em" if rectangle.widthunit = MeasurementUnitType.Pixels | MeasurementUnitType.Em.
Then, there is a
public static IEnumerable<int> GetIntBasedEnumMembers(Type #enum)
{
foreach (FieldInfo fi in #enum.GetFields(BindingFlags.Public | BindingFlags.Static))
yield return (int)fi.GetRawConstantValue();
}
Which will let me traverse any enum with int based values and return the int values themselves.
I find these to be very useful in an allready useful concept.
It all depends what your trying to do with the enum.
If you are trying to stop your developers from passing magic numbers into your operations and you want to keep the data referential integrity intact with your DB then, YES! Use T4-Templates (using your ORM) to go to your MeasurementUnitTypes table and generate a enum with the ID, Name and Description columns matching the enum’ int, Enum_Name and Description Attribute (nice approach for additional field\data to enum #danijels) as suggested above. If you add a new Measurement Type to your MeasurementUnitTypes table you can just right click and run the T4-Template and the enum code is generated for that new row added in the table. I don’t like hard-coded data in my application that doesnt link to my DB hence the mention of the T4-Template approach. It is not extensible otherwise...what if some other external system wants to retrieve our Measurement Criteria used in our system, then it is hard-coded in the system and you can't expose it to the client via a service. That left there.
If the purpose is not data related and you have some logic assigned to a specific enum then NO! this violates the SOLID (Open close principle) as you would somewhere in your application apply a switch or bunch of Ifs to action the logic per enum, ALSO if you did it REALLY bad these switches or Ifs are all over the show....good luck adding a new enum... so it is not open for extension and closed for modification as you need to modify existing code, as per the SOLID principle.
If your choice is 2 then I suggest then to replace your enum with the following using the example from #danijels comment:
public interface IMeasurementUnitType
{
int ID { get; }
string Description { get; }
// Just added to simulate a action needed in the system
string GetPrintMessage(int size);
}
The above code defines the interface (code contract) that each measurement should adhere to. Now lets define Percentage and Pixel measurement :
public class PixelsMeasurementUnitType : IMeasurementUnitType
{
public int ID => 1;
public string Description => "Pixel";
public string GetPrintMessage(int size)
{
return $"This is a {Description} Measurement that is equal to {size} pixels of the total screen size";
}
}
public class PercentMeasurementUnitType : IMeasurementUnitType
{
public int ID => 2;
public string Description => "Persentage";
public string GetPrintMessage(int size)
{
return $"This is a {Description} Measurement that is equal to {size} persent of total screen size (100)";
}
}
So wee have defined two types, we would use them in code as follows:
var listOfMeasurmentTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(IMeasurementUnitType).IsAssignableFrom(p)
&& !p.IsInterface)
.ToList();
Here we grab all the TYPES that extends the IMeasurementUnitType interface and NOT the interface itself. Now we can use the Activator to create instances of the classes to populate our UI controls:
public IEnumerable<IMeasurementUnitType> GetInstantiatedClassesFromTypes(List<Type> types)
{
foreach (var type in types)
{
yield return (IMeasurementUnitType)Activator.CreateInstance(type);
}
}
You can change the code above to be generic for any type, AND NOW life happens and the client give a new measuring unit type called Point as a new requirement, I don't need to CHANGE ANY code, just add the new type (extend the code NOT modify). The new type will automatically be picked up in the application.
public class PointMeasurementUnitType : IMeasurementUnitType
{
public int ID => 3;
public string Description => "Point";
public string GetPrintMessage(int size)
{
return $"This is a {Description} Measurement that is equal to {size} points of total screen size";
}
}
a Good idea would be to cache your types for performance benefits upon starting your application or try and use a DI container of your choice.
Also, one can argue that somewhere in you application you would need to distinguish between types and I agree, however you want to keep apples with apples. So try as far as possible to apply the same principle used for this types. If this type is used in some sort of Graphics processor (for example) class then have a IGraphicsProcessor and have your concrete classes that differentiate between these types for example PersentageAndPixelGraphicsProcessor (that extends from IGraphicsProcessor) or if it distinguishes only one type call it PersentageGraphicsProcessor.
Sorry for the HUGE SA but I really like enum's however I feel when you trying to separate logic using a enums it is a STRONG anti-pattern.
comments welcome,
This isn't an answer, as much as contributing to a list of Enum anti-patterns.
During a code review this morning, I ran into a case similar to the following, all in the same class.
Two cases:
Before drinking
After drinking
..
public enum ListEnum
{
CategoryOne,
CategoryTwo,
CategoryThree,
CategoryFour
}
public class UIELementType
{
public const string FactoryDomain = "FactoryDomain";
public const string Attributes = "Attributes";
}
Using enums in not anti-pattern. In some books about refactoring this code is used to demonstrate how to replace it with polymorphism. It would be OK when you overuse enums in code.
I see having two switch statements as a symptom of non-OO design as explained further in this answer.
Related
I am trying to create an elegant and extensible way of querying a dictionary which maps an enum to a set of strings.
So I have this class SearchFragments that has the dictionary in it. I then want a method wherein consumers of this class can simply ask "HasAny" and, this is the bit where I am struggling, simply pass in some query like expression and get the boolean answer back.
public class SearchFragments
{
private readonly IDictionary<SearchFragmentEnum, IEnumerable<string>> _fragments;
public SearchFragments()
{
_fragments = new Dictionary<SearchFragmentEnum, IEnumerable<string>>();
}
public bool HasAny(IEnumerable<SearchFragmentEnum> of)
{
int has = 0;
_fragments.ForEach(x => of.ForEach(y => has += x.Key == y ? 1 : 0));
return has >= 1;
}
}
The problem with the way this currently is, is that consumers of this class now have to construct an IEnumerable<SearchFragmentEnum> which can be quite messy.
What I am looking for is that the consuming code will be able to write something along the lines of:
searchFragments.HasAny(SearchFragmentEnum.Name, SearchFragmentEnum.PhoneNumber)
But where that argument list can vary in size (without me having to write method overloads in the SearchFragments class for every possible combination (such that if new values are added to the SearchFragmentEnum at a future date I won't have to update the class.
You can use params[]
public bool HasAny(params SearchFragmentEnum[] of)
{ ...
Sidenote: you know that LIN(Q) queries should just query a source and never cause any side-effects? But your query does unnecessarily increment the integer:
_fragments.ForEach(x => of.ForEach(y => has += x.Key == y ? 1 : 0));
Instead use this (which is also more efficient and more readable):
return _fragments.Keys.Intersect(of).Any();
An even more efficient alternative to this is Sergey's idea:
return of?.Any(_fragments.ContainsKey) == true;
For variable sized arguments in c# you use the params keyword:
public int HasAny(params SearchFragmentEnum[] of)
The .Net API usually offers a couple of overloads of this for performance reasons; the parameters passed are copied into a new array. Explicitely providing overloads for the most common cases avoids this.
public int HasAny(SearchfragmentEnum of1)
public int HasAny(SearchFragmentEnum of1, SearchFragmentEnum of2)
etc.
Instead of using params you could also consider marking your enum with the [Flags] attribute. Parameters could than be passed like HasAny(SearchFragmentEnum.Name | SearchFragmentEnum.PhoneNumber. Examples abundant on StackOverflow (e.g. Using a bitmask in C#)
Use the params keyword to allow a varying number of arguments. Further, you can simplify your code by looping over the smaller of array. Also, you are using a dictionary that has O(1) key check, so it is uneccessary to have an inner loop:
public bool HasAny(params SearchFragmentEnum[] of)
{
foreach(var o in of) {
if (this._fragments.ContainsKey(o))
return true;
}
return false;
}
or shorter with LINQ
public bool HasAny(params SearchFragmentEnum[] of) {
return of?.Any(_fragments.ContainsKey) ?? false;
}
Good afternoon all!
As a part of getting a better grip on some of the most aspects of object based programming, I've started to attempt something far larger than I have done in the past. Hereby I'm trying to learn about inheritance, code reuse, using classes far more extensively, and so on.
For this purpose I am trying to piece together all the parts required for a basic RPG/dungeon crawler.
I know this has been done a billion times before, but I find that actually trying to code something like it takes you through a lot more problems than you might think, which is a great way to learn (I think).
For now I have only loaded up a WPF application, since my interest is 95% on being able to piece together the working classes, routines, functions, etc. And not so much interested in how it will look. I am actually reading up on XNA, but since I am mostly trying to get a grip on the basic workings, I don't want to complicate those aspects with the graphical side of things just yet.
The problem I am now facing is that when I would a character to attack or defend, it should know from which other character it came, or to which one it should be pointed. I figured I could either use a GUID, or a manually appointed ID. But the problem is that I don't really know how I can implement such a thing.
The thing that I figured was that I could maybe add a reference to an array (Character[]), and have a SearchByID function loop through them to find the right one, and return it. Like so:
internal Character SearchByID(string _ID)
{
foreach(Character charToFind in Character[])
{
if(charToFind.ID == _ID)
return charToFind;
}
}
This of course has to be altered a bit due to the return at the moment, but just to give you an idea.
What I am stuck on is how to create the appropriate array outside of the "Character"-class? I can fill it up just fine, but how do I go about having it added above class level?
The way the "Character"-class is built up is that every new character instantiates from the Character class. The constructor then loads the appropriate values. But other than this, I see no possibility to initialize an array outside of this.
If it is preferable to post the entire code that I have, that will be no problem at all!
Thanks for any insights you may provide me with.
I think you can just use the Character-class and pass other Characters to it, for example:
public class Character
{
public string Name { get; private set; }
public int HitPoints { get; private set; }
public int Offense { get; private set; }
public int Defense { get; private set; }
public Character(string name, int hitPoints, int offense, int defense)
{
Name = name;
HitPoints = hitPoints;
Offense = offense;
Defense = defense;
}
public void Defend(Character source)
{
HitPoints = HitPoints - (source.Offense - Defense);
if (HitPoints <= 0)
{
Console.WriteLine("{0} died", Name);
}
}
public void Attack(Character target)
{
// Here you can call the other character's defend with this char as an attacker
target.Defend(this);
if (target.HitPoints <= 0)
{
Console.WriteLine("{0} killed {1}", Name, target.Name);
}
}
}
The thing with object oriented programming is that you have to start thinking in objects. Objects are like boxes when they're concrete. You can make new ones and give them some properties, like a name, height, width, hitpoints, whatever. You can also let these objects perform actions. Now a simple box won't do much itself, but a character can do various things, so it makes sense to put these actions in the Character-class.
Besides having Characters, you might have a Game-class which manages the game-state, characters, monsters, treasure chests etc...
Now this simple example may cause you to gain HitPoints when your defense is higher than the attacker's offense, but that's details, I'll leave the exact implementation up to you.
I guess you want a way to insert characters in an array when they are instantiated..
You can make a static array or list
So,your class in my opinion should be
class Character
{
static List<Character> characterList=new List<Character>();//all characters are here
public Character(string id,...)
{
//initialize your object
characterList.Add(this);//store them in the list as and when created
}
internal Character SearchByID(string _ID)
{
foreach(Character charToFind in characterList)
{
if(charToFind.ID == _ID)
return charToFind;
}
}
}
As you may be knowing static members are associated with the class not with the object.So,when you create a new character object it would be automatically added to the characterList
Unless you are dealing with seperate processes, e.g. client-server, you probably don't want to use "Id"s at all.
Whereever you are passing string _ID around, pass the actual Character instead. This saves you looking up in an array or whatever.
Post more code, and I can show you what I mean.
You could use a dictionary, instantiated in your controller class:
Dictionary<Guid, Character> _characterList = new Dictionary<Guid, Character>();
Initialise:
var someCharacter = new Character() { stats = something };
var otherCharacter = new Character() { stats = anotherThing };
var char1Id = Guid.NewGuid();
var char2Id = Guid.NewGuid();
_characterList.Add(char1Id, someCharacter);
_characterList.Add(char2Id, otherCharacter);
then, to access characters:
var charToFind = _characterList[char1Id];
or
var charToFind = _characterList.Single(c => c.Name = "Fred The Killer");
or whatever else...
Check out keyed collection
KeyedCollection
It is like a dictionary where the key is a property of class.
You will be able to reference a Character with
Characters[id]
Syntax
On your Character class overrite GetHashCode and Equals for performance.
If you use Int32 for the ID then you will get a perfect hash.
Very fast and O(1).
I have some code that works on the color structure like this
public void ChangeColor()
{
thisColor.R = thisColor.R + 5;
}
Now I need to make a method that changes a different variable depending on what it is passed. Here is what the code looks like now.
public void ChangeColor(int RGBValue)
{
switch(RGBValue)
{
case 1:
thisColor.R = thisColor.R + 5;
break;
case 2:
thiscolor.B = thisColor.B + 5;
break;
}
}
Now, this is something I would normally never question, I'd just throw a #region statement around it and call it a day, but this is just an example of what I have, the actual function is quite long.
I want it to look like this:
public void ChangeColor(int RGBValue)
{
thiscolor.RGBValue = thiscolor.RGBValue;
}
So essentially the value would refer to the variable being used. Is there a name for this? Is this what Reflection is for? Or something like that... Is there a way to do this?
I'm not 100% sure if this is what you want. But with the given example, it sounds like this might be what you're after.
you might be able to use the ref keyword:
public void ChangeColor(ref int color)
{
color += 5;
}
void SomeMethod()
{
ChangeColor(ref thisColor.R); //Change the red value
ChangeColor(ref thisColor.B); //Change the blue value
}
This is definitely not what reflection is for. In fact, there seem to be a number of issues here. Let's review here - you want to change the following method:
public void ChangeColor(int RGBValue)
{
switch(...)
{
case ...
case ...
case ...
}
}
Into something like this:
public void ChangeColor(int RGBValue)
{
thisColor.{something-from-RGBValue} += 5;
}
The problems with this are:
The name of the method, ChangeColor, does not precisely describe what the method actually does. Perhaps this is an artifact of anonymization, but nevertheless it's a terrible name for the method.
The parameter, RGBValue, does not accurately describe what the argument is or does. The name RGBValue and the type int makes it sound like an actual RGB color value, i.e. 0x33ccff for a light blue. Instead it chooses which of R, G, or B will be set.
There are only 3 valid values for the parameter, and yet the range of possible values is completely unrestricted. This is a recipe for bugs. Worse, individual values are used as magic numbers inside the method.
But perhaps most important of all, the "clean/quick method" you are asking for is precisely the abstraction that this method purports to provide! You're writing a method that intensifies the hue, and in order to keep the method short, you're asking for... a method to intensify the hue. It doesn't make sense!
I can only assume that you want to do this because you have many different things you might want to do to a Color, for example:
public void Brighten(...) { ... }
public void Darken(...) { ... }
public void Desaturate(...) { ... }
public void Maximize(...) { ... }
And so on and so forth. And you're trying to avoid writing switch statements for all.
Fine, but don't eliminate the switch entirely; it is by far the most efficient and readable way to write this code! What's more important is to distill it down to one switch instead of many, and fix the other problems mentioned above. First, let's start with a reasonable parameter type instead of an int - create an enumeration:
public enum PrimaryColor { Red, Green, Blue };
Now, start from the idea that there may be many actions we want to perform on one of the primary colors of a composite color, so write the generic method:
protected void AdjustPrimaryColor(PrimaryColor pc, Func<byte, byte> adjustFunc)
{
switch (pc)
{
case PrimaryColor.Red:
internalColor.R = adjustFunc(internalColor.R);
case PrimaryColor.Green:
internalColor.G = adjustFunc(internalColor.G);
default:
Debug.Assert(pc == PrimaryColor.Blue,
"Unexpected PrimaryColor value in AdjustPrimaryColor.");
internalColor.B = adjustFunc(internalColor.B);
}
}
This method is short, easy to read, and will likely never have to change. It is a good, clean method. Now we can write the individual action methods quite easily:
public void Brighten(PrimaryColor pc)
{
AdjustPrimaryColor(pc, v => v + 5);
}
public void Darken(PrimaryColor pc)
{
AdjustPrimaryColor(pc, v => v + 5);
}
public void Desaturate(PrimaryColor pc)
{
AdjustPrimaryColor(pc, v => 0);
}
public void Maximize(PrimaryColor pc)
{
AdjustPrimaryColor(pc, v => 255);
}
The (significant) advantages to this are:
The enumeration type prevents callers from screwing up and passing in an invalid parameter value.
The general Adjust method is easy to read and therefore easy to debug and easy to maintain. It's also going to perform better than any reflection-based or dictionary-based approach - not that performance is likely a concern here, but I'm mainly saying this to note that it certainly isn't going to be worse.
You don't have to write repeated switch statements. Each individual modifier method is exactly one line.
Eventually, somewhere, you're actually going to have to write some code, and I would much rather that code be an extremely simple switch statement than a mess of reflection, delegates, dictionaries, etc. The key is to generalize this work as much as possible; once you've done that and created that abstraction, then you can start writing one-liner methods to do the "real" work.
It's a bit awkward, but you can pass a property 'by ref' like this:
int ThisColor { get; set; }
public void ChangeColor(Func<int> getter, Action<int> setter)
{
setter(getter() + 5);
}
public void SomeMethod()
{
ChangeColor(() => ThisColor, (color) => ThisColor = color);
}
This is less expensive than reflection and it's compile-time checked (with reflection, you'd have to pass a string to a GetProperty call and the string name could potentially diverge from the property name in later refactoring.)
I would tend to use a dictionary rather than what i suspect could end up being a large switch statement so if you created a
Dictionary<int,Func<int,int>> map = new Dictionary<int, Func<int, int>>();
Each item in your dictionary could take then input and return the new value
so you your method you would be able to call
public int ChangeColor(int rgbValue)
{
return map[rgbValue](rgbValue);
}
which will execute the delegate specific for the Rgb value you insert, to assign a delegate you simply add a new entry to the map
map.Add(5,x => x+5);
If I understand you correctly, you'd like to write a method that takes some symbol (or property name) and modifies the property of the structure using defined by this symbol. This isn't easily possible in C# (you could of course use reflection, but...).
You could do similar thing using Dictionary containing delegates for reading and writing the value of the property. However, that will still be a bit lengthy, because you'll need to initialize the dictionary. Anyway, the code might look like this:
var props = new Dictionary<string, Tuple<Func<Color, int>, Action<Color, int>>>
{ "R", Tuple.Create(c => c.R, (c, r) => c.R = r),
"G", Tuple.Create(c => c.G, (c, g) => c.G = g),
"B", Tuple.Create(c => c.B, (c, b) => c.B = b) };
This creates a dictionary that contains string (name of the property) as the key and a tuple with getter delegate and setter delegate for each of the property. Now your ChangeColor method could look like this:
public void ChangeColor(string propName) {
var getSet = props[propName];
getSet.Item2(thisColor, getSet.Item1(thisColor) + 5);
}
The code would be more readable if you used your own type with Get property and Set property instead of Tuple with properties named Item1 and Item2. This solution may be useful in some scenarios, but you still need to explicitly list all the properties when initializing the dictionary.
This might be what your looking for, you may want to add some error handling though.
It will work with any kind of property with public get; and set; methods.
And if you want to there is ways to reduce use of "magic-strings".
public static void ChangeProperty<T>(this object obj, string propertyName, Func<T,T> func)
{
var pi = obj.GetType().GetProperty(propertyName);
pi.SetValue(obj, func((T)pi.GetValue(obj, null)), null);
}
public void Change()
{
thisColor.ChangeProperty<int>("R", (x) => x + 5);
}
Well, it's kind of hard to tell what's really going on since you've given a very simplified example.
But, what I'm really reading is that you want to have a method that will perform one of a number of possible modifications to local state based upon one of the parameters of the method.
Now, is the operation the same, except for what it's being done to?
Ultimately, you have to have some code that understandds that maps an input to a desired operation. How much that can be generalized depends upon how similar the actions are (if it's always 'add 5 to a property' you have more generalization options...).
Some options you have are:
Write a class which encapsulates the Color struct.
Use a lookup table of Actions, as suggested by Kev Hunter.
Write a switch statement.
Pass in a parameter which contains a virtual method which can be executed on the internal data (or just pass in an Action<> directly) - avoiding the lookup
And... that's about it, really. Which one of these makes the most sense probably depends more on your actual use case (which we don't really have a lot of info on) than anything else.
We have some stuff that may be exported into various formats. Currently we have these formats represented by an enum like this:
[Flags]
public enum ExportFormat
{
None = 0x0,
Csv = 0x1,
Tsv = 0x2,
Excel = 0x4,
All = Excel | Csv | Tsv
}
Problem is that these must be enumerated and they also need a translation or description in the ui. Currently I solved this by creating two extension methods. They work, but I don't really like them or the solution at all... they feel kind of smelly. Problem is I don't really know how I could do this better. Does anyone have any good alternatives? These are the two methods:
public static IEnumerable<ExportFormat> Formats(this ExportFormat exportFormats)
{
foreach (ExportFormat e in Enum.GetValues(typeof (ExportFormat)))
{
if (e == ExportFormat.None || e == ExportFormat.All)
continue;
if ((exportFormats & e) == e)
yield return e;
}
}
public static string Describe(this ExportFormat e)
{
var r = new List<string>();
if ((e & ExportFormat.Csv) == ExportFormat.Csv)
r.Add("Comma Separated Values");
if ((e & ExportFormat.Tsv) == ExportFormat.Tsv)
r.Add("Tab Separated Values");
if ((e & ExportFormat.Excel) == ExportFormat.Excel)
r.Add("Microsoft Excel 2007");
return r.Join(", ");
}
Maybe this is the way to do this, but I have a feeling there must be better ways to do it. How could I refactor this?
You could use the Formats method inside Describe to avoid doing all the bit operations at multiple places, like this:
private static Dictionary<ExportFormat, string> FormatDescriptions =
new Dictionary<ExportFormat,string>()
{
{ ExportFormat.Csv, "Comma Separated Values" },
{ ExportFormat.Tsv, "Tab Separated Values" },
{ ExportFormat.Excel, "Microsoft Excel 2007" },
};
public static string Describe(this ExportFormat e)
{
var formats = e.Formats();
var descriptions = formats.Select(fmt => FormatDescriptions[fmt]);
return string.Join(", ", descriptions.ToArray());
}
This way, it is easy to incorporate the string descriptions from an external source or localization, as hinted above.
The only other way comes to my mind is the usage of the System.Attribute class.
public class FormatDescription : Attribute
{
public string Description { get; private set; }
public FormatDescription(string description)
{
Description = description;
}
}
And then use Reflection with in your Describe function.
The only benefit of this method would be to have definition and the description at one place.
Dupe: How do I have an enum bound combobox with custom string formatting for enum values?
You could write an TypeConverter that reads specified attributes to look them up in your resources. Thus you would get multi-language support for display names without much hastle.
Look into the TypeConverter's ConvertFrom/ConvertTo methods, and use reflection to read attributes on your enum fields.
Addition:
Scroll down in the linked post for a implementation of a TypeConverter that does part of what is required for full support.
This would support an application where you have several languages at the same time, not only code name -> english name.
Remember that this is only the display name, never the stored value. You should always store the code name, or the integer value, to support users with different locales using the same data.
I have a class that I have to call one or two methods a lot of times after each other. The methods currently return void. I was thinking, would it be better to have it return this, so that the methods could be nested? or is that considerd very very very bad? or if bad, would it be better if it returned a new object of the same type? Or what do you think? As an example I have created three versions of an adder class:
// Regular
class Adder
{
public Adder() { Number = 0; }
public int Number { get; private set; }
public void Add(int i) { Number += i; }
public void Remove(int i) { Number -= i; }
}
// Returning this
class Adder
{
public Adder() { Number = 0; }
public int Number { get; private set; }
public Adder Add(int i) { Number += i; return this; }
public Adder Remove(int i) { Number -= i; return this; }
}
// Returning new
class Adder
{
public Adder() : this(0) { }
private Adder(int i) { Number = i; }
public int Number { get; private set; }
public Adder Add(int i) { return new Adder(Number + i); }
public Adder Remove(int i) { return new Adder(Number - i); }
}
The first one can be used this way:
var a = new Adder();
a.Add(4);
a.Remove(1);
a.Add(7);
a.Remove(3);
The other two can be used this way:
var a = new Adder()
.Add(4)
.Remove(1)
.Add(7)
.Remove(3);
Where the only difference is that a in the first case is the new Adder() while in the latter it is the result of the last method.
The first I find that quickly become... annoying to write over and over again. So I would like to use one of the other versions.
The third works kind of like many other methods, like many String methods and IEnumerable extension methods. I guess that has its positive side in that you can do things like var a = new Adder(); var b = a.Add(5); and then have one that was 0 and one that was 5. But at the same time, isn't it a bit expensive to create new objects all the time? And when will the first object die? When the first method returns kind of? Or?
Anyways, I like the one that returns this and think I will use that, but I am very curious to know what others think about this case. And what is considered best practice.
The 'return this' style is sometimes called a fluent interface and is a common practice.
I like "fluent syntax" and would take the second one. After all, you could still use it as the first, for people who feel uncomfortable with fluent syntax.
another idea to make an interface like the adders one easier to use:
public Adder Add(params int[] i) { /* ... */ }
public Adder Remove(params int[] i) { /* ... */ }
Adder adder = new Adder()
.Add(1, 2, 3)
.Remove(3, 4);
I always try to make short and easy-to-read interfaces, but many people like to write the code as complicated as possible.
Chaining is a nice thing to have and is core in some frameworks (for instance Linq extensions and jQuery both use it heavily).
Whether you create a new object or return this depends on how you expect your initial object to behave:
var a = new Adder();
var b = a.Add(4)
.Remove(1)
.Add(7)
.Remove(3);
//now - should a==b ?
Chaining in jQuery will have changed your original object - it has returned this.
That's expected behaviour - do do otherwise would basically clone UI elements.
Chaining in Linq will have left your original collection unchanged. That too is expected behaviour - each chained function is a filter or transformation, and the original collection is often immutable.
Which pattern better suits what you're doing?
I think that for simple interfaces, the "fluent" interface is very useful, particularly because it is very simple to implement. The value of the fluent interface is that it eliminates a lot of the extraneous fluff that gets in the way of understanding. Developing such an interface can take a lot of time, especially when the interface starts to be involved. You should worry about how the usage of the interface "reads"; In my mind, the most compelling use for such an interface is how it communicates the intent of the programmer, not the amount of characters that it saves.
To answer your specific question, I like the "return this" style. My typical use of the fluent interface is to define a set of options. That is, I create an instance of the class and then use the fluent methods on the instance to define the desired behavior of the object. If I have a yes/no option (say for logging), I try not to have a "setLogging(bool state)" method but rather two methods "WithLogging" and "WithoutLogging". This is somewhat more work but the clarity of the final result is very useful.
Consider this: if you come back to this code in 5 years, is this going to make sense to you? If so, then I suppose you can go ahead.
For this specific example, though, it would seem that overloading the + and - operators would make things clearer and accomplish the same thing.
For your specific case, overloading the arithmetic operators would be probably the best solution.
Returning this (Fluent interface) is common practice to create expressions - unit testing and mocking frameworks use this a lot. Fluent Hibernate is another example.
Returning a new instance might be a good choice, too. It allows you to make your class immutable - in general a good thing and very handy in the case of multithreading. But think about the object creation overhead if immutability is of no use for you.
If you call it Adder, I'd go with returning this. However, it's kind of strange for an Adder class to contain an answer.
You might consider making it something like MyNumber and create an Add()-method.
Ideally (IMHO), that would not change the number that is stored inside your instance, but create a new instance with the new value, which you return:
class MyNumber
{
...
MyNumber Add( int i )
{
return new MyNumber( this.Value + i );
}
}
The main difference between the second and third solution is that by returning a new instance instead of this you are able to "catch" the object in a certain state and continue from that.
var a = new Adder()
.Add(4);
var b = a.Remove(1);
var c = a.Add(7)
.Remove(3);
In this case both b and c have the state captured in a as a starting point.
I came across this idiom while reading about a pattern for building test domain objects in Growing Object-Oriented Software, Guided by Tests by Steve Freeman; Nat Pryce.
On your question regarding the lifetime of your instances: I would exspect them to be elligible for garbage collection as soon as the invocation of Remove or Add are returning.