I installed CodeCracker
This is my original method.
//Add
public bool AddItemToMenu(MenuMapper mapperObj)
{
using (fb_databaseContext entities = new fb_databaseContext())
{
try
{
FoodItem newItem = new FoodItem();
newItem.ItemCategoryID = mapperObj.ItemCategory;
newItem.ItemName = mapperObj.ItemName;
newItem.ItemNameInHindi = mapperObj.ItemNameinHindi;
entities.FoodItems.Add(newItem);
entities.SaveChanges();
return true;
}
catch (Exception ex)
{
//handle exception
return false;
}
}
}
This is the recommended method by CodeCracker.
public static bool AddItemToMenu(MenuMapper mapperObj)
{
using (fb_databaseContext entities = new fb_databaseContext())
{
try
{
var newItem = new FoodItem
{
ItemCategoryID = mapperObj.ItemCategory,
ItemName = mapperObj.ItemName,
ItemNameInHindi = mapperObj.ItemNameinHindi,
};
entities.FoodItems.Add(newItem);
entities.SaveChanges();
return true;
}
catch (Exception ex)
{
//handle exception
return false;
}
}
}
As far as I know Static methods occupy memory when the application intialize irrespective if they are called or not.
When I alrady know the return type then why should I use var keyword.
Why this way of Object intializer is better.
I am very curios to get these answer, as it can guide me in a long way.
Adding one more method:-
private string GeneratePaymentHash(OrderDetailMapper order)
{
var payuBizzString = string.Empty;
payuBizzString = "hello|" + order.OrderID + "|" + order.TotalAmount + "|FoodToken|" + order.CustomerName + "|myemail#gmail.com|||||||||||10000";
var sha1 = System.Security.Cryptography.SHA512Managed.Create();
var inputBytes = Encoding.ASCII.GetBytes(payuBizzString);
var hash = sha1.ComputeHash(inputBytes);
var sb = new StringBuilder();
for (var i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString().ToLower();
}
As far as I know Static methods occupy memory when the application intialize irrespective if they are called or not.
All methods do that. You are probably confusing this with static fields, which occupy memory even when no instances of the class are created. Generally, if a method can be made static, it should be made static, except when it is an implementation of an interface.
When I already know the return type then why should I use var keyword.
To avoid specifying the type twice on the same line of code.
Why this way of Object intializer is better?
Because it groups the assignments visually, and reduces the clutter around them, making it easier to read.
Static methods don't occupy any more memory than instance methods. Additionally, your method should be static because it doesn't rely in any way on accessing itself (this) as an instance.
Using var is most likely for readability. var is always only 3 letters while many types are much longer and can force the name of the variable much further along the line.
The object initializer is, again, most likely for readability by not having the variable name prefix all the attributes. It also means all your assignments are done at once.
In most cases, this tool you're using seems to be about making code more readable and clean. There may be certain cases where changes will boost performance by hinting to the compiler about your intentions, but generally, this is about being able to understand the code at a glance.
Only concern yourself with performance if you're actually experiencing performance issues. If you are experiencing performance issues then use some profiling tools to measure your application performance and find out which parts of your code are running slowly.
As far as I know Static methods occupy memory when the application
initialize irrespective if they are called or not.
This is true for all kind of methods, so that's irrelevant.
When I already know the return type then why should I use var keyword.
var is a personal preference (which is a syntactic sugar). This analyzer might think since the return type is already known, there is no need to use type explicitly, so, I recommend to use var instead. Personaly, I use var as much as possible. For this issue, you might wanna read Use of var keyword in C#
Why this way of Object intializer is better.
I can't say object initializer is always better but object initialize supplies that either your newItem will be null or it's fully initialized since your;
var newItem = new FoodItem
{
ItemCategoryID = mapperObj.ItemCategory,
ItemName = mapperObj.ItemName,
ItemNameInHindi = mapperObj.ItemNameinHindi,
};
is actually equal to
var temp = new FoodItem();
newItem.ItemCategoryID = mapperObj.ItemCategory;
newItem.ItemName = mapperObj.ItemName;
newItem.ItemNameInHindi = mapperObj.ItemNameinHindi;
var newItem = temp;
so, this is not the same as your first one. There is a nice answer on Code Review about this subject. https://codereview.stackexchange.com/a/4330/6136 Also you might wanna check: http://community.bartdesmet.net/blogs/bart/archive/2007/11/22/c-3-0-object-initializers-revisited.aspx
A lot of these are personal preferences but most coding standards allow other programmers to read your code easier.
Changing the static method to an instance takes more advantage of OO concepts, it limits the amount of mixed state and also allows you to add interfaces so you can mock out the class for testing.
The var keyword is still statically typed but because we should concentrate on naming and giving our objects more meaningful so explicitly declaring the type becomes redundant.
As for the object initialisation this just groups everything that is required to setup the object. Just makes it a little easier to read.
As far as I know Static methods occupy memory when the application intialize irrespective if they are called or not.
Methods that are never called may or may not be optimized away, depending on the compiler, debug vs. release and such. Static vs. non-static does not matter.
A method that doesn't need a this reference can (and IMO should) be static.
When I already know the return type then why should I use var keyword
No reason. There's no difference; do whatever you prefer.
Why this way of Object intializer is better.
The object initializer syntax generates the same code for most practical purposes (see answer #SonerGönül for the details). Mostly it's a matter of preference -- personally I find the object initializer syntax easier to read and maintain.
Related
I have something like the following code:
public class MainAppClass : BaseClass
{
public IList<Token> TokenList
{
get;
set;
}
// This is execute before any thread is created
public override void OnStart()
{
MyDataBaseContext dbcontext = new MyDataBaseContext();
this.TokenList = dbcontext.GetTokenList();
}
// After this the application will create a list of many items to be iterated
// and will create as many threads as are defined in the configuration (5 at the momment),
// then it will distribute those items among the threads for parallel processing.
// The OnProcessItem will be executed for every item and could be running on different threads
protected override void OnProcessItem(AppItem processingItem)
{
string expression = getExpressionFromItem();
expression = Utils.ReplaceTokens(processingItem, expression, this);
}
}
public class Utils
{
public static string ReplaceTokens(AppItem currentProcessingItem, string expression, MainAppClass mainAppClass)
{
Regex tokenMatchExpression = new Regex(#"\[[^+~][^$*]+?\]", RegexOptions.IgnoreCase);
Match tokenMatch = tokenMatchExpression.Match(expression)
if(tokenMatch.Success == false)
{
return expression;
}
string tokenName = tokenMatch.Value;
// This line is my principal suspect of messing in some way with the multiple threads
Token tokenDefinition = mainAppClass.TokenList.Where(x => x.Name == tokenName).First();
Regex tokenElementExpression = new Regex(tokenDefintion.Value);
MyRegexSearchResult evaluationResult = Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).FirstOrDefault();
string tokenValue = string.Empty;
if (evaluationResult != null && evaluationResult.match.Groups.Count > 1)
{
tokenValue = evaluationResult.match.Groups[1].Value;
}
else if (evaluationResult != null && evaluationResult.match.Groups.Count == 1)
{
tokenValue = evaluationResult.match.Groups[0].Value;
}
expression = expression.Replace("[" + tokenName + "]", tokenValue);
return expression;
}
}
The problem I have right now is that for some reason the value of the token replaced in the expression get confused with one from another thread, resulting in an incorrect replacement as it should be a different value, i.e:
Expression: Hello [Name]
Expected result for item 1: Hello Nick
Expected result for item 2: Hello Sally
Actual result for item 1: Hello Nick
Actual result for item 2: Hello Nick
The actual result is not always the same, sometimes is the expected one, sometimes both expressions are replaced with the value expected for the item 1, or sometimes both expressions are replaced with the value expected for the item 2.
I'm not able to find what's wrong with the code as I was expecting for all the variables within the static method to be in its own scope for every thread, but that doesn't seem to be the case.
Any help will be much appreciated!
Yeah, static objects only have one instance throughout the program - creating new threads doesn't create separate instances of those objects.
You've got a couple different ways of dealing with this.
Door #1. If the threads need to operate on different instances, you'll need to un-static the appropriate places. Give each thread its own instance of the object you need it to modify.
Door #2. Thread-safe objects (like mentioned by Fildor.) I'll admit, I'm a bit less familiar with this door, but it's probably the right approach if you can get it to work (less complexity in code is awesome)
Door #3. Lock on the object directly. One option is to, when modifying the global static, to put it inside a lock(myObject) { } . They're pretty simple and straight-foward (so much simpler than the old C/C++ days), and it'll make it so multiple modifications don't screw the object up.
Door #4. Padlock the encapsulated class. Don't allow outside callers to modify the static variable at all. Instead, they have to call global getters/setters. Then, have a private object inside the class that serves simply as a lockable object - and have the getters/setters lock that lockable object whenever they're reading/writing it.
The tokenValue that you're replacing the token with is coming from evaluationResult.
evaluationResult is based on Utils.GetRegexMatches(currentProcessingItem, tokenElementExpression).
You might want to check GetRegexMatches to see if it's using any static resources, but my best guess is that it's being passed the same currentProcessingItem value in multiple threads.
Look to the code looks like that splits up the AppItems. You may have an "access to modified closure" in there. For example:
for(int i = 0; i < appItems.Length; i++)
{
var thread = new Thread(() => {
// Since the variable `i` is shared across all of the
// iterations of this loop, `appItems[i]` is going to be
// based on the value of `i` at the time that this line
// of code is run, not at the time when the thread is created.
var appItem = appItems[i];
...
});
...
}
In order to use the Contains method, what is better (is any difference), declare a static fieldwith the HashSet or declare it inline (new HashSet { SomeEnum.SomeValue1, SomeEnum.SomeValue2, ... }.Contains(SomeEnum.SomeValue1))
I ask that because in some cases I only going mto use the hashset once, and for me is better to have it on the code and not in some static attribute
Example inline (What I wanna use):
public void Validate(Type type) {
if(!new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 }.Contains(type)) {
//do something
}
if(new HashSet<Type> { Type.TYPE_2, Type.TYPE_3, Type.TYPE_4, Type.TYPE_5 }.Contains(type)) {
//do something
}
}
Example static (What I prefer not to use):
private static HashSet<Type> _values1 = new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 };
private static HashSet<Type> _values2 = new HashSet<Type> { Type.TYPE_2, Type.TYPE_3, Type.TYPE_4, Type.TYPE_5 };
public void Validate(Type type) {
if(!_values1.Contains(type)) {
//do something
}
if(_values2.Contains(type)) {
//do something
}
}
Example using logical expressions (What I don't want to use):
public void Validate(Type type) {
if(type != Type.TYPE_1 && type != Type.TYPE_2 && type != Type.TYPE_3 && type != Type.TYPE_4) {
//do something
}
if(type == Type.TYPE_2 || type == Type.TYPE_3 || type == Type.TYPE_4 || type == Type.TYPE_5) {
//do something
}
}
If you have not identified this as a bottleneck through performance testing, the the "right" way is just to use code that makes the most sense to people reading it. That's somewhat subjective, so there may not be a "right" way, but any approach that's not easy to understand will be the "wrong" way.
I would probably just use an inline-declared array, unless the list of values is reusable in other methods, or it's so long that it gets in the way of reading what the method is trying to do.
public void Validate(Type type) {
if(!new[] { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 }.Contains(type)) {
//do something
}
}
If you have identified this as a definite performance bottleneck (meaning you're probably doing this check millions of times per second, then you'll probably want to do performance testing on a few different approaches, because the correct answer depends on how many items are in the set you're trying to match against.
Besides the approaches you've suggested, here are a couple of other possibilities that will probably be faster (but again, you'd need to test them to make sure:
Flags Enum
It looks like you're using enum values. If that enum type has a small number of potential values, you could make it into a flags enum and then use bitwise logic to determine in a single CPU operation whether the given value matches any of the values you're looking for.
[Flags]
public enum Type
{
TYPE_1 = 1,
TYPE_2 = 1<<1,
TYPE_3 = 1<<2,
TYPE_4 = 1<<3,
TYPE_5 = 1<<4,
// etc...
}
Usage:
const Type toMatch = (Type.TYPE_1 | Type.TYPE_2 | Type.TYPE_3 | Type.TYPE_4);
if((type & toMatch) == 0)
{
// do something
}
Switch statement
The compiler is really good at figuring out what will be the fastest approach, so if you use a switch statement it can decide whether to compile that to a series of if/else checks, a HashSet-style approach, or a jump table, depending on the number and values of items you're trying to check.
switch(type)
{
case Type.TYPE_1:
case Type.TYPE_2:
case Type.TYPE_3:
case Type.TYPE_4:
break;
default:
// do something
break;
}
If no new items are going to be added then your static method is the correct way to do it
private static HashSet<Type> _values = new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 };
public void Validate(Type type) {
if(!_values.Contains(type)) {
//do something
}
}
All collections in the System.Collections namespace are thread safe for read only operations so this is a perfectly acceptable way to do it.
If you did it your "preferred" way it would still work, however you would be re-creating the collection every time you call the function and that is a unnecessary overhead that would definitely hurt performance.
Keeping with the "infrequent" or "once" usage of the lookup in mind, as hinted by the post..
If the lookup is used only within the single method then I would use an inline approach, however I would us an array (and I actually do quite often). I may or may may not use an intermediate (local) variable, depending on if I it makes the code more clear or easy to adapt in the future.
I wouldn't use a static (or even instance) variable because:
The sequence is not shared in this case;
The of trivial amount of resources to create the object (especially for an array) is minimal;
The GC is really good with short-lived objects .. and, more importantly, there is no need to extend the lifetime
If I wanted to share this lookup across several methods, I would look into creating a getter that returned a new object (which covers #2 and #3 above while meeting the new requirement). With a local variable, individual methods would only create one new lookup per invocation.
I generally use an array because:
The syntax is marginally simpler (the type can be inferred and omitted);
The array (especially the construction) is more lightweight than a HashSet, yet provides the required lookup functionality;
Searching a small array is likely fast enough (as there is a very small n)
I would not use various long-hand forms if it makes the particular code harder to follow. The task is "contains", not some more complex conditional logic.
Unless there is an actual performance problem, do it a clean and simple way and move on with more interesting tasks.
According to the requirement we have to return a collection either in reverse order or as
it is. We, beginning level programmer designed the collection as follow :(sample is given)
namespace Linqfying
{
class linqy
{
static void Main()
{
InvestigationReport rpt=new InvestigationReport();
// rpt.GetDocuments(true) refers
// to return the collection in reverse order
foreach( EnquiryDocument doc in rpt.GetDocuments(true) )
{
// printing document title and author name
}
}
}
class EnquiryDocument
{
string _docTitle;
string _docAuthor;
// properties to get and set doc title and author name goes below
public EnquiryDocument(string title,string author)
{
_docAuthor = author;
_docTitle = title;
}
public EnquiryDocument(){}
}
class InvestigationReport
{
EnquiryDocument[] docs=new EnquiryDocument[3];
public IEnumerable<EnquiryDocument> GetDocuments(bool IsReverseOrder)
{
/* some business logic to retrieve the document
docs[0]=new EnquiryDocument("FundAbuse","Margon");
docs[1]=new EnquiryDocument("Sexual Harassment","Philliphe");
docs[2]=new EnquiryDocument("Missing Resource","Goel");
*/
//if reverse order is preferred
if(IsReverseOrder)
{
for (int i = docs.Length; i != 0; i--)
yield return docs[i-1];
}
else
{
foreach (EnquiryDocument doc in docs)
{
yield return doc;
}
}
}
}
}
Question :
Can we use other collection type to improve efficiency ?
Mixing of Collection with LINQ reduce the code ? (We are not familiar with LINQ)
Looks fine to me. Yes, you could use the Reverse extension method... but that won't be as efficient as what you've got.
How much do you care about the efficiency though? I'd go with the most readable solution (namely Reverse) until you know that efficiency is a problem. Unless the collection is large, it's unlikely to be an issue.
If you've got the "raw data" as an array, then your use of an iterator block will be more efficient than calling Reverse. The Reverse method will buffer up all the data before yielding it one item at a time - just like your own code does, really. However, simply calling Reverse would be a lot simpler...
Aside from anything else, I'd say it's well worth you learning LINQ - at least LINQ to Objects. It can make processing data much, much cleaner than before.
Two questions:
Does the code you currently have work?
Have you identified this piece of code as being your performance bottleneck?
If the answer to either of those questions is no, don't worry about it. Just make it work and move on. There's nothing grossly wrong about the code, so no need to fret! Spend your time building new functionality instead. Save LINQ for a new problem you haven't already solved.
Actually this task seems pretty straightforward. I'd actually just use the Reverse method on a Generic List.
This should already be well-optimized.
Your GetDocuments method has a return type of IEnumerable so there is no need to even loop over your array when IsReverseOrder is false, you can just return it as is as Array type is IEnumerable...
As for when IsReverseOrder is true you can use either Array.Reverse or the Linq Reverse() extension method to reduce the amount of code.
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.
I have inherited a project that has some huge switch statement blocks, with some containing up to 20 cases. What is a good way to rewrite these?
Why would you want to rewrite them in a different structure? If you really have 20 cases that have to be handled individually, a switch/case is the way to go. A big chain of if/then logic would be horrible to maintain.
Polymorphism is another option if you are using an object-oriented language. Each subclass would implement it's own functionality in the method.
Polymorphism. But it may not be a trivial refactoring.
Some examples and refs:
Refactoring (Googe books)
Switch Statement code smell and Polymorphism
Refactoring switch-statements
As others have pointed out, it depends on the switch statement. However, in the past I have refactored switch statements by proceeding in the following way. Suppose we have a switch statement like this, with a lot of repeating code
switch(x){
case 1:
makeitso("foo");
globalLog += "foo";
case 2:
makeitso("bar");
globalLog += "bar";
case 3:
makeitso("baz");
globalLog += "baz";
...
default:
throw("input error");
}
the first thing to do is to recognize the parts that are common (in the real world, this will probably be a little more substantial)
makeitso([some string]);
globalLog += [some string];
and turn that into a function
function transformInput(somestring) {
makeitso(somestring);
globalLog += somestring;
}
then for the parts that change in each case, use a hash or an array;
var transformvalues = ["foo", "bar", "baz"];
from here we can do this:
var tvals = ["foo", "bar", "baz" ... ];
function transformInput(somestring) {
makeitso(somestring);
globalLog += somestring;
}
var tval = tvals[x];
if(tval!==undefined) {
transformInput(tval);
} else {
throw ("invalid input");
}
And with tvals factored out of the switch statement, it could even be provided externally to expand the number of cases you can handle. Or you could build it dynamically. In the real world, the switch statement will often have special cases, however. I leave that as an excercise for the reader.
Three suggestions (echoing some already given):
Maybe a switch isn't as bad as you think. It can be ugly if the case blocks are large. Shorten them by extracting the logic into methods.
In an OO language, polymorphism might be the answer, as many have pointed out.
In a functional language, like Javascript, write a function that returns the function you need to run for whatever input. That might use a switch statement itself, or it might use a lookup table.
You could always use a lookup table.
There's nothing wrong with having 20 cases in a switch statement. You can tidy the code by refactoring and, at the very least, move the case processing into methods/functions.
Depending on what the switch statement is evaluating, you may want to refactor it using the Strategy Pattern. Take a look at this post for an example of replacing a switch on enum values with separate classes to handle each function.
It also may be that using the switch with 20 cases may actually be the best course of action for it. As long as it's readable and each result clearly conveys what the action is there's no need to really refactor it.
In general, I think you should refactor only when you need to, such as when you want to add more features, but the current design isn't up for the task. You should then refactor without adding the new functionality, and only then add the new feature.
In other circumstances, don't bother with refactoring. Do it when you need to, otherwise there are probably more important things to do.
If you really really need to, then the Visitor Design Pattern is a common switch-case replacement, though you should note it does have drawbacks. (i.e., check out www.objectmentor.com/resources/articles/acv.pdf)
It depends what the switch statement is doing.
If it's matching characters or strings, say in a parser, and you don't have the same set of patterns repeated everywhere in the code, then a switch statement might be ok.
If it's matching (say) an integer against a list of allowed values, you can create a base class and a set of derived classes for each value. Then, whatever generates the integer data in the first place can create an instance of the derived class with all of the switch statement "answers" instead.
A third option is to create a data structure that maps patterns to actions (i.e., functions or objects with virtual methods). You can look up the switch value in this data strucutre, and execute the appropriate action.
if it's working without major bugs (by not major I mean they don't make you pull your hair out) why bother refactor it? Don't refactor everything.
If you want, you can change it to polymorphism, but this will be a shotgun surgery, you'll probably have to refactor a whole lot more than just this switch block.
Visit https://github.com/Pedram-Ahmadpour/Switch-Case
Client side
Create an instance of your Condition, then pass a condition to Condition object by Switch() function.
int sense = 2;
ConditionSense conditionSense = new ConditionSense();
conditionSense.Switch(sense);
Server side
Create a condition action. This interface defines how to execute a Condition.
public interface IAction
{
void Do();
}
Create list of cases you want. These classes must implement condition action and ICase; Keep them light.
public class CaseCry : IAction, ICase<int?>
{
public int? Key { get { return 2; } }
public void Do()
{
Sense.Cry cry = new Sense.Cry();
cry.Act();
}
}
ICase just holds a Key that it is used by Switch() function to navigate the cases.
public interface ICase<TCase>
{
TCase Key { get; }
}
Create a Condition class that it Inherites SwitchCase generic abstract class.
Add all cases witch you want to Cases property.
Define a Switch() function and navigate Cases property to find matches cases, then execute them as a condition action.
public class ConditionSense : SwitchCase<int?>
{
public ConditionSense()
{
Cases = new List<ICase<int?>>
{
new CaseSmile(),
new CaseCry()
};
DefaultCases = new List<ICase<int?>> {
new CaseNoSense()
};
}
public void Switch(int? key)
{
IEnumerable<IAction> matches = Cases.Where(p => p.Key.Equals(key))
.Select(p => p as IAction);
if (matches.Count() > 0)
foreach (IAction match in matches)
match.Do();
else
foreach (IAction defaultCase in DefaultCases)
defaultCase.Do();
}
}
Smile, Cry..., can be huge, don't worry about size of them; condition action and ICase keep them lazy load.
public class Sense
{
public class Smile
{
public void Act()
{
Console.WriteLine("I'm smiling :-)");
}
}
public class Cry
{
public void Act()
{
Console.WriteLine("I'm crying :-(");
}
}
public class NoSense
{
public void Act()
{
Console.WriteLine("I've no sense :-|");
}
}
}