Is it considered readable to call methods inside the IF condition? [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Is this way of writing IF conditions considered good coding style in Java and C# languages or not?
if (checkIfIdInFirstRange()){
//call Range1 handling method
}else if(checkIfIdInSecondRange()){
//call Range2 handling method
}else{
//call error handling method
}
I'm wondering about the method inside the IF condition itself, or would it be better to make it like:
int idInRange = getIdInRange();
//handle isInRange

I think this is fine.
Even better is if you phrase your methods like a question, or flows with the if statement
if (thisConditionIsTrue()){
// Do this
}elseif(anotherConditionIsTrue()){
// Do this instead
}elseif(isThisParameterOkay(someParameter)){
// Yeh do this
}
Some hardcore purists will even say that if you have > 3 levels of indentation, your method is too nested and should be split into smaller methods.

Doing this is IMHO good coding practice as long as the method calls don't have any side effects.
e.g.
if checkIfIdInFirstRange() this is OK:
private bool checkIfIdInFirstRange()
{
return firstRange.Contains(ID);
}
But doing this might create confusion:
private bool checkIfIdInFirstRange()
{
SomeStringProperty = "totally new value that no caller would ever expect after a call to this method";
return firstRange.Contains(ID);
}
Another possible solution - depending on the actual type of your problem at hand - could be to define an interface / base class and use polymorphism.
example:
internal abstract class A
{
public void DoSomething(int ID)
{
if(IsInRange(ID))
DoSomethingProtected(ID);
}
protected abstract bool IsInRange(int ID);
protected abstract void DoSomethingProtected(int ID);
}
internal class B : A
{
private List<int> firstRange = new List<int> { 42, 23, 5};
protected override bool IsInRange(int ID)
{
return firstRange.Contains(ID);
}
protected override void DoSomethingProtected(int ID)
{
Console.WriteLine("{0}", ID);
}
}
public class Program
{
public static void Main(string[] args)
{
B foo = new B();
foo.DoSomething(3);
foo.DoSomething(42);
}
}
CAUTION: code written without IDE to hand.

Yes. It would be much more readable if you used just a little whitespace. Bunching it up like that makes it hard to tell where things begin and end and makes else if() look like a function call.
if ( checkIfIdInFirstRange() ) {
//call Range1 handling method
}
else if ( checkIfIdInSecondRange() ) {
//call Range2 handling method
}
else {
//call error handling method
}
Making the extra variable is likely to make code harder to read since you have to define them all before the if/else stack. However, it all depends on the case. Sometimes it might be better to use a variable if you will be using an expensive function many times or if you can make the variable have a more descriptive name than the function.

Actually it is also required if you want to test multiple methods and use short-circuit evaluation.
For instance, this is safe:
if (isResourceAvailable() && isResourceValid()) {
...
}
while this may no be:
bool resAvailable = isResourceAvailable();
bool resValid = isResourceValid(); // can you call that alone?
if (resAvailable && resValid ) {
...
}

It is good style as long as the methods you call don't just do something that would be clearer if it was coded in place:
if ( a > 0 && a < 10 ) doSomething();
is better than
if ( isInRange(a, 0, 10) ) doSomething();

Eh, it's mostly up to the coder but declaring the int is a bit more readable.

It's OK to write methods in the IF condition statement. But if the method will be used more than one time, you should first use a local variable to store the return value and use the variable as the IF condition

You can aim at writing function / method names that will make the code more readable where they are used. Like:
if (idInFirstRange()){
//call Range1 handling method
}else if(idInSecondRange()){
//call Range2 handling method
}else{
Also, usual convention for functions returning bool is that they start with is - isIdInFirstRange
Lastly, try avoiding such if-else ( and switch ) ladder. Try to use Dictionaries in such cases. ( https://stackoverflow.com/questions/6506340/if-if-else-or-switch-case/6506403#6506403 )

Although this practice is not wrong or condemned by any best practices guidelines, if you have more than one call within if condition it can be a bit difficult to know which call refused to enter if statement during a debug session.
if (idInFirstRange() && idInSecondRange()){
//call Range handling method
//if didn't reach this point, who was the responsible (idInFirstRange or idInSecondRange)?
}else if(idInSecondRange()){
//call Range2 handling method
}else{
//call something else
}

Related

TryParse dilemma-Dealing with out parameters [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I never liked out and ref parameters.When I see them in action they give me a feeling that something is messy about the design.
I thought that the only exception was the so called TryXXX pattern that returns a boolean as the function result (whether everything was fine or something went wrong) and an out parameter for the real result, until I read this article today and It made me think if there's a better pattern to implement this kind of methods.
I thought that we could either have a function that returns more than one result(or as the article says a tuple)
Tuple<Exception,T> TryParseT(object obj)
or a function that accepts a callback function for success :
void TryParseT(object obj,Action<T> success)
The question is , which one is better from a functional design point of view ?
UPDATE :
To rephrase my question , I want to know which of these two functions more complies with Functional Programming principles and why ?
Essentially the problem is that to follow the functional programming approach you should always provide a return value for an input value. So the returning void route isn't the way to go. You need to return a value that can represent success (and hold the successful result) and failure (and hold no result).
The closest to that is where you have returned a Tuple which includes the exception. However you then don't have the 'infrastructure' to deal with the Tuple reliably once you've got it. So the code scaffolding around it will be repeated.
Take a look at this library language-ext. It deals with improving the out problem for TryParse using its implementation of Option<T>.
string inp = "123";
// Attempts to parse the value, uses 0 if it can't
int value1 = parseInt(inp).IfNone(0);
// Functional alternative to above
// Attempts to parse the value, uses 0 if it can't
int value2 = ifNone(parseInt(inp), 0);
// Attempts to parse the value and then pattern matches the result
int value3 = parseInt(inp).Match(
Some: x => x * 2,
None: () => 0
);
// Functional alternative to above
// Attempts to parse the value and then pattern matches the result
int value4 = match( parseInt(inp),
Some: x => x * 2,
None: () => 0
);
The library also allows you to just check that something is valid:
if( parseInt(inp) )
return 1;
else
return 0;
And allows for comparisons without actually extracting the value:
if( parseInt(inp) == 123 )
return 123;
else
return 0;
As well as logical operations:
var allValid = parseInt(x) && parseInt(y) && parseInt(z);
var someValid = parseInt(x) || parseInt(y) || parseInt(z);
And finally LINQ expressions which can often remove the need for if-then-else or matching:
var res = from x in parseInt(inp1)
from y in parseInt(inp2)
from z in parseInt(inp3)
select x + y + z;
It also has TryGetValue extensions for IDictionary, IReadOnlyDictionary, IImmutableDictionary and IImmutableSet that instead return Option<T> and can be used as above.
The most elegant method is
int Parse(string value)
The Tryxxxx methods only exist for an implementation detail named performance. If you are seeking elegance you can use the Parse method and handle any errors by failing fast.
You can instead return a tuple but this will cost an additional allocation on the heap since Tuple is a reference type.
A better solution in terms of performance (if you care) would be aKeyValuePair. But it hides (like tuple) the semantics behind generic data types which is not optimal for code clarity. A better way to signal failure than by defining some convention that the first bool of the tuple contains the failure state is by defining your own data type.
struct ParseResult<T>
{
public bool Success { get; private set; }
public T Value { get; private set; }
public ParseResult(T value, bool success):this()
{
Value = value;
Success = success;
}
}
class Program
{
static ParseResult<int> TryParse(string s)
{
int lret = 0;
if (int.TryParse(s, out lret))
{
return new ParseResult<int>(lret, true);
}
else
{
return new ParseResult<int>(lret, false);
}
}
static void Main(string[] args)
{
string test = "1";
var lret = TryParse(test);
if( lret.Success )
{
Console.WriteLine("{0}", lret.Value);
}
}
}
That approach is still quite efficient and spares you the out parameters at the cost of the allocation of a cheap container object.

Is it possible to have a Func<bool> as a while condition

Good evening,
I was wondering if I could do something like:
while(true)
{
MyEnum currentValue = GetMyEnumValueFromDB();
if(currentValue == MyEnum.BreakIfYouGetThis)
break;
else if(currentValue == MyEnum.AlsoBreakIfYouGetThis)
break;
else
//Do some computing
}
But instead of having a while(true) loop, I'd want to encapsulate the conditional logic in a Func and execute it like this:
while(new Func<bool>(/* what goes here? */))
{
//Do some computing
}
In my case at least, it would look much cleaner, but i'm not sure how to do it (kinda new at Func/Action..).
EDIT hope this clarifies:
It could also be done like this:
while(GetMyEnumValueFromDB() != MyEnum.BreakIfYouGetThis &&
GetMyEnumValueFromDB() != MyEnum.AlsoBreakIfYouGetThis)
{
//Do some computing
}
But that's 2 call to the database...
Thanks =)
Well you could have:
Func<bool> condition = ...;
while (condition())
{
}
Is that what you're thinking of? It's not really clear...
EDIT: In the example you've given, I'd use something like:
private static readonly MyEnum[] BreakEnumValues = {
MyEnum.BreakIfYouGetThis,
MyEnum.AlsoBreakIfYouGetThis
};
...
while (!BreakEnumValues.Contains(GetMyEnumValueFromDB()))
{
...
}
Or:
private static bool ShouldBreak(MyEnum enumFromDatabase)
{
return enumFromDatabase == MyEnum.BreakIfYouGetThis ||
enumFromDatabase == MyEnum.AlsoBreakIfYouGetThis;
}
...
while (!ShouldBreak(GetMyEnumValueFromDB))
{
...
}
EDIT: To counter KeithS's answer, this is entirely valid:
while (new Func<bool>(() => {
Console.WriteLine("Evaluating...");
return true;
})()) {
Console.WriteLine("In loop");
count++;
if (count == 5)
{
break;
}
}
It's horrible, but it's valid. (It can be made slightly less horrid by explicitly calling Invoke, but it's still not nice.)
You could do that, but if you don't have a compelling reason to do so (like you're passing the condition function in as a parameter), I'd just wrap your logic in a function and call it directly:
while(KeepGoing())
{
//Do stuff
}
bool KeepGoing()
{
// Check conditions for continuing
var value = GetMyEnumValueFromDB();
return value != MyEnum.BreakIfYouGetThis && value != MyEnum.AlsoBreakIfYouGetThis;
}
First off, a database call in a while loop is a bad idea. Query what you'll need beforehand and loop accordingly.
It appears that polymorphism can be your friend here. If you need to keep the same flow, you can do something like this:
interface IWhileLoopContinuable
{
bool KeepGoing {get;}
void DoWork();
}
Then you can use TakeWhile on this enumerable:
foreach(var item in queriedAsIWhileLoopContinuable.TakeWhile(c => c.KeepGoing))
{
item.DoWork();
}
All that being said, you could just query for what you want and work on that.
Well, first off you cannot "new" a Func, just like you can't new up any delegate type. You must instead assign an existing named method or function literal (aka anonymous delegate, lambda, etc) to initialize a Func variable.
//these won't compile; Func has no constructor
Func<bool> condition = new Func<bool>();
//As Jon Skeet notes, these will compile because of language-provided syntax,
//even though Funcs have no constructor with a delegate parameter.
Func<bool> condition = new Func<bool>(SomeNamedMethodReturnsBool);
Func<bool> condition = new Func<bool>(()=>true);
//and these will compile because you're directly assigning the delegate
Func<bool> condition = SomeNamedMethodReturnsBool;
Func<bool> condition = ()=>true;
You actually cannot do what you want in C#; an anonymous delegate must be assigned to a variable or parameter in order to be used. It cannot be used in-place as a "function literal" in the abstract sense.
Even if you could, the utility of such a statement escapes me. The delegate would not be re-instantiated every time (the compiler turns anonymous delegates into named private functions of the containing class, with mashup names), but you're adding a layer onto the call stack just to evaluate a constant expression that could be placed directly into the parenthesis of the while() statement. The main utility of an anonymous delegate would be that you could swap out lambdas at runtime, and in order to do that you MUST have a variable.

Please show me a situtation which shows `need` for Delegates (or) function pointers

I'm going take a class on "Delegates and Callbacks" to students who are learning level programmers. They have basic c/c++ & c# background. Instead of directly showing how to use them. I want to show "Why Function Pointers?" first. I want to start with an example situation and ask them "How will you do this"? and make them realize the need for something and then introduce them to FunctionPointers, Delegates & CallBacks.
So, Can any one show me a good example which shows the need for Delegates in C# (or) function pointers in C/C++. I don't want example of event handling in GUI example and I don't want demonstration of "How to use delegates" with an examples of kind add2numbers etc..
I'm looking for something practical example where they could feel the need of FunctionPointers, Delegates & CallBacks.
If there are any good articles, please post them.
You can show them an example of filtering a list of items in several places in your software.
For example, you might have
public List<Person> GetMale(List<Person> people)
{
List<Person> results = new List<Person>();
foreach (Person p in people)
{
if (p.IsMale)
results.Add(p);
}
return results;
}
or
public List<Person> GetFemale(List<Person> people)
{
List<Person> results = new List<Person>();
foreach (Person p in people)
{
if (!p.IsMale)
results.Add(p);
}
return results;
}
To avoid repeating the foreach iteration in every method, you will want to extract the actual condition (i.e. a predicate in this case), and have it implemented somewhere else.
So you will replace these two methods with:
public List<Person> Filter(List<Person> people, Func<bool, Person> match)
{
List<Person> results = new List<Person>();
foreach (Person p in people)
{
if (match(p))
results.Add(p);
}
return results;
}
and then call it in your code like this:
List<Person> malePersons = Filter(people, p => p.IsMale);
List<Person> femalePersons = Filter(people, p => !p.IsMale);
Note that the actual condition is now extracted outside of the iterating block, and you can reuse the same method to create any custom filtering logic you like. By extracting this logic, you are delegating the problem to someone else, making your code loosely coupled.
Using C# 2.0 anonymous method syntax, calling this method would look like this:
List<Person> malePersons = Filter(people,
delegate (Person p) { return p.IsMale; });
List<Person> femalePersons = Filter(people,
delegate (Person p) { return !p.IsMale; });
or using actual methods:
List<Person> malePersons = Filter(people, MaleMatch);
List<Person> femalePersons = Filter(people, FemaleMatch);
where predicates are defined as:
private bool MaleMatch(Person p)
{
return p.IsMale;
}
private bool FemaleMatch(Person p)
{
return !p.IsMale;
}
It is important to note that we are not passing the result of these methods, but actual method "pointers", so actual results will be returned when the method is called inside the Filter method.
Note also that LINQ in .Net 3.5 already contains a Where extension method which does the same thing like this example, and many other methods which use delegates for conditions, projecting and other stuff, so you basically only need to pass a delegate with the appropriate signature.
I'm not sure why you don't want to use a GUI example: the concept of "when I click a button, I want X to happen - now how to I express X?" is quite a good one.
Other examples:
I want to start a thread: how do I express what I want it to do?
I want to filter some data: how do I express the filter?
I want to project some data: how do I express the projection?
I want to download a file from the web asynchronously: how do I express what I want to happen when it's finished downloading?
Basically each of these is a case of saying, "I want to express some code in a simple way." In each case you could use a single method interface - delegates/function pointers are just a more convenient way of doing that.
Indeed, if some of the students are used to using single method interfaces (e.g. Runnable in Java) then that's probably a good starting point. Imagine if you could implement an interface by saying "just use this method over here..." (And in Java 7 it looks like you'll be able to do just that; they're using single method interfaces and method references in lieu of dedicated delegate types.) From a C# background you can also compare the IComparer<T> interface with the Comparer<T> delegate.
Of course when you've got the idea of delegates, you can then introduce lambda expressions (if it's a C# course) showing them how useful it is to be able to express that bit of logic "inline". Then show them how it's useful to be able to interact with the local environment, using lambdas as closures...
I would show how to write/use a generic sort function/method, which takes a callback parameter as a predicate.
Asyncrhonous calls: you call a method that will execute in background (usually a remote service call), and you want to specify which code will execute when the method finishes (since you indeed need to know when the method finishes). See here for more details: http://msdn.microsoft.com/en-us/magazine/cc301332.aspx
The Observer-Pattern is an example. The main reason for Callbacks/Delegates is, that you want to reduce coupling and increase flexibility of the architecture for further developments.
Delegates allow you to view code as data, so anytime you want something done in a certain way but leave the details to the caller delegates come in handy. Sorting is probably the prime example, but there are many others as illustrated by some of the answers.
E.g. let's say you want to time something. Since you basically want to go through the same timing steps no matter what you're timing, you can let your timing method take a delegate and time that in a consistent way. In pseudo code it could look something like this
TimeThis(method_pointer) {
setup_timing();
method_pointer(); // invoke the method
report_timing();
}
Yet another example
Let's assume that you want to define a method that draws a curve for any function of the form f(x). First attempt
public DrawFunction(string f)
{
for (int x = 0; x <= 10; x++) {
DrawPoint( ??? ); // How are you calling f(x) here?
}
}
Delegates are a mean of using methods as data. I.e. a variable or property or parameter of a delegate type can store a method. We can solve our problem using a delegate like this:
public DrawFunction(Func<double, double> f)
{
for (int x = 0; x <= 10; x++) {
DrawPoint(10.0 * x, f(x));
}
}
Let's assume that we have defined this method
public double Square(double x)
{
return x * x;
}
Now you can draw the function like this
DrawFunction(Square);
Note that we do not call (execute) Square here, therfore we don't place braces () after Square.
We can also use lambda expressions instead. We obtain the same result with
DrawFunction(x => x*x);
Another curve
DrawFunction(x => 1.0/(1.0 + x*x));
You can take the example of how events are implemented in .NET; your students can easily relate to it.
To Jon Skeet. Yes, every delegate may be represented as single-method interface, but you may not implement different versions of it in one class. With delegates (function pointers) you may have as many implementations as you want - different names but same signature:
class C
{
int Add(int a, int b)
{
return a + b;
}
int Mul(int a, int b)
{
return a * b;
}
};
But you cannot implement the same interface twice (see my class C above). For C++ and C# although we can emulate delegates with interfaces. But for C in is necessary intrument to make callback and runtime polymorphism. In C++ and C# it much for compaitibility and convience.
namespace WindowsApplication10
{
/// <summary>
/// This delegate will be used by the button
/// </summary>
public delegate Point GetCenter();
public partial class Form1 : Form
{
CentralButton central;
public Form1()
{
InitializeComponent();
central = new CentralButton(this.GetCenter);
this.Controls.Add(central);
}
public Point GetCenter()
{
return new Point(this.Width / 2, this.Height / 2);
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
central.UpdateCenter();
}
}
/// <summary>
/// This button calculates its location in the center of the parent
/// </summary>
public class CentralButton : Button
{
GetCenter myGetCenterMethod;
public CentralButton(GetCenter findCenterMethod)
{
myGetCenterMethod = findCenterMethod;
}
public void UpdateCenter()
{
// use the delegate for obtain the external information
this.Location = myGetCenterMethod();
}
}
}
Checkout the Can your programming language do this? article from Joel.
He has few good examples where there are two functions that are almost doing the same thing, but use different functions to achieve a certain task.
alert("get the lobster");
PutInPot("lobster");
PutInPot("water");
alert("get the chicken");
BoomBoom("chicken");
BoomBoom("coconut");
Refactored with functions passed as arguments:
function Cook( i1, i2, f )
{
alert("get the " + i1);
f(i1);
f(i2);
}
Cook( "lobster", "water", PutInPot );
Cook( "chicken", "coconut", BoomBoom );

C#: Returning 'this' for method nesting?

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.

What's the best alternative to an out of control switch statement?

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 :-|");
}
}
}

Categories

Resources