Using one else with multiple if statements in C# - c#

Is there a way to quickly check the following logic in C#?
if (a)
{
}
if (b)
{
}
if (c)
{
}
else //none of the above, execute if all above conditions are false
{
/* do something only if !a && !b && !c */
}
This differs from using if-else in that a, b, and c can all be true at once, so I can't stack them that way.
I want to run the else block when a, b, and c are all false without writing if (!a && !b && !c). This is because the code can get quite messy when the if conditions become more complex. It requires rewriting a lot of code.
Is this possible?

Firstly, no, else blocks only respect the if clause immediately above them, so you'll need an alternative.
This option isn't especially "clean", but I'd do:
bool noneAreTrue = true;
if(a)
{
noneAreTrue = false;
}
if(b)
{
noneAreTrue = false;
}
if(c)
{
noneAreTrue = false;
}
if(noneAreTrue)
{
//execute if all above conditions are false
}
Also, if your conditions are really pretty big, I recommend the rule G28 (Encapsulate Conditionals) from the book Clean Code from Robert C. Martin.
It is pretty verbose, but can be easier to read in some instances:
public void YourMethod()
{
if(SomeComplexLogic())
{
}
if(SomeMoreLogic())
{
}
if(EvenMoreComplexLogic())
{
}
if(NoComplexLogicApply())
{
}
}
private bool SomeComplexLogic(){
return stuff;
}
private bool EvenMoreComplexLogic(){
return moreStuff;
}
private bool EvenMoreComplexLogic(){
return evenMoreStuff;
}
private bool NoComplexLogicApply(){
return SomeComplexLogic() && EvenMoreComplexLogic() && EvenMoreComplexLogic();
}

How about combine the concepts of Strategies and Specifications
var strategies = _availableStrategies.All(x => x.IsSatisfiedBy(value));
foreach (var strategy in strategies)
{
strategy.Execute(context);
}
if (!strategies.Any()) {
// run a different strategy
}

Rather than encapsulate some complex condition in a method that you will only ever call once or twice, I would just keep in a variable. This is also more readable than using some marker boolean as other answers suggest.
A contrived example,
bool isBlue = sky.Color == Colors.Blue;
bool containsOxygen = sky.Atoms.Contains("oxygen") && sky.Bonds.Type == Bond.Double;
bool canRain = sky.Abilities.Contains("rain");
if(isBlue)
{
}
if(containsOxygen)
{
}
if(canRain)
{
}
if(!isBlue && !containsOxygen && !canRain)
{
}
Now we have abstracted what might otherwise be complex conditions into readable English!

Related

VDS.RDF.GraphHandler for skipping Triples

I want to parse only some data out of a ~100 MB rdf cell line ontology. So far I am interested in 169.796 out of 1.387.097 tripples (1.217.301 tripples being skipped).
I need ~24 seconds using the handler below to create the graph. This is only some seconds less then parsing the ontology in total.
Is there something I could improve in skipping the tuples I am not interested in?
Thanks!
private class MyHandler : VDS.RDF.GraphHandler
{
public MyHandler(IGraph g)
: base(g)
{
}
protected override bool HandleTripleInternal(Triple t)
{
if (t.Predicate is UriNode uri
&& uri.Uri.AbsoluteUri != "http://www.w3.org/2000/01/rdf-schema#subClassOf"
&& uri.Uri.AbsoluteUri != "http://www.w3.org/2000/01/rdf-schema#label")
{
return true;
}
else if (t.Object is LiteralNode l && l.Language == "zh")
{
return true;
}
return base.HandleTripleInternal(t);
}
}
To make the comparison of nodes a bit faster you could try comparing directly with a UriNode created from the graph instead of comparing URI strings. If you use the IGraph.CreateUriNode() method in your filter constructor to create nodes for rdfs:subClassOf and rdfs:label and then use IUriNode.Equals() as your comparator then you should find that the node comparison can use a faster object reference equality rather than a string comparison.
private class MyHandler : GraphHandler
{
private readonly IUriNode _rdfsSubClassOf;
private readonly IUriNode _rdfsLabel;
public MyHandler(IGraph g)
: base(g)
{
_rdfsSubClassOf = g.CreateUriNode(UriFactory.Create("http://www.w3.org/2000/01/rdf-schema#subClassOf"));
_rdfsLabel = g.CreateUriNode(UriFactory.Create("http://www.w3.org/2000/01/rdf-schema#label"));
}
protected override bool HandleTripleInternal(Triple t)
{
if (t.Predicate is UriNode uri
&& !uri.Equals(_rdfsSubClassOf)
&& !uri.Equals(_rdfsLabel))
{
return true;
}
else if (t.Object is LiteralNode l && l.Language == "zh")
{
return true;
}
return base.HandleTripleInternal(t);
}
}
However that is only going to speed up the filter and I suspect that if you profile the parse of the file you will find that the majority of the time is spent in parsing the syntax to create the triple that is passed to your filter. There isn't really a way to get around this issue in the dotNetRDF handler architecture.

IsConnectedToNetwork for Windows8 WinRT Fails

Anyone know a good way to see if the user is online/offline? When I use public static bool IsConnectedToNetwork(); and see if it's false/true it seems to always be true, even when I shut down my internet to test it...
Am I missing something?
public static bool nets()
{
bool go =
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
if (go == false)
{
return false;
}
return true;
}
Now, in my start-up I run:
var ba = nets();
if (ba == false)
{
txtHeader.Text = "err";
}
if (ba != false)
{
// Code
}
I also tried:
public static bool IsConnectedToNetwork();
I use
public static bool IsConnectedToInternet()
{
ConnectionProfile connectionProfile = NetworkInformation.GetInternetConnectionProfile();
return (connectionProfile!=null && connectionProfile.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess);
}
You could ping one of the few well known URLs to see if you get responses.
I have a way that seems to work pretty decent, especially noticing sometimes Ethernet could appear to be in use even when its not in Windows 8 RTM... That's why nothing seems to work!
However, doing the following is a good choice for me to test...
var profile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
var interfaceType = profile.NetworkAdapter.IanaInterfaceType;
// 71 is WiFi & 6 is Ethernet
if (interfaceType == 71 | interfaceType == 6)
{
// Run Code
}
/* 3G/Mobile Detect
else if (interfaceType == 243 | interfaceType == 244)
{
// Run Code if you need to use a less quality feature.
}*/
else
{
txtHeader.Text = "Error, Check connection or Try connecting to the Internet...";
}

Refactor my C# code : if-else statement and code repetition

Given:
private void UpdataFieldItems(List<FieldItemBase> existingFieldItems, List<FieldItemBase> selectedFieldItems)
{
List<FieldItemBase> newFieldItemsSelected;
var fieldSelectionChanges = GetFieldSelectionChanges(out newFieldItemsSelected);//retuns a Flagged enum
if (Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem))
{
StartEditMode();
SetColumnDescriptorsToAdd(newFieldItemsSelected);
UpdateItems(selectedFieldItems);
SetColumnsToShow();
CustomizeAlignmentAndCellFormatters(_tfaTableGrid.TableGrid);
if (_tfaTableGrid.TableGrid.ColumnDescriptors.Count() > 0)
{
SetAdditionalFirstGroupedColumn();
}
StopEditMode();
}
else if (Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary))
{
StartEditMode();
UpdateItems(fieldItems);
SetColumnsToShow();
if (_tfaTableGrid.TableGrid.ColumnDescriptors.Count() > 0)
{
SetAdditionalFirstGroupedColumn();
}
StopEditMode();
}
else if (Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Order) ||
Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedCustomFieldItem) ||
Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.RemovedItem))
{
UpdateItems(fieldItems);
SetColumnsToShow();
}
Invalidate();
}
//Coding.cs
public static bool EnumHas(FieldSelectionChanges selectionChanges, FieldSelectionChanges valueToCheck)
{
return (selectionChanges & valueToCheck) == valueToCheck;
}
I am willing to refactor the above code.
There are two things that i don't like about the code above:
1) Writing same method calls in different cases, its not being possible to pull out the common method calls from these cases.
2) The readability of this code is very bad. It would be very confusing to understand and debug, if later needed.
Can someone suggest a design pattern for this code? or some way to improve upon the above two concerns?
Thanks for your interest.
Use extract method for body of each if statement
Create Dictionary> to choose appropriate action for fieldSelectionChanges. This is Strategy pattern
I would make the different conditions more expressive in terms of what it actually does to your application seeing you already use quite descriptive method names for the actions. Something like:
private void UpdataFieldItems(List<FieldItemBase> existingFieldItems, List<FieldItemBase> selectedFieldItems)
{
List<FieldItemBase> newFieldItemsSelected;
var fieldSelectionChanges = GetFieldSelectionChanges(out newFieldItemsSelected);//retuns a Flagged enum
if (IsValidChange(fieldSelectionChanges))
{
List<FieldItemBase> targetfields = null;
if (IsInEditMode(fieldSelectionChanges))
StartEditMode();
if (IsItemAdded(fieldSelectionChanges))
{
SetColumnDescriptorsToAdd(newFieldItemsSelected);
targetFields = selectedFieldItems;
}
else
targetFields = existingFieldItems;
UpdateItems(targetFields);
SetColumnsToShow();
if (IsItemAdded(fieldSelectionChanges))
CustomizeAlignmentAndCellFormatters(_tfaTableGrid.TableGrid);
if (IsInEditMode(fieldSelectionChanges))
{
if (_tfaTableGrid.TableGrid.ColumnDescriptors.Count() > 0)
SetAdditionalFirstGroupedColumn();
StopEditMode();
}
}
Invalidate();
}
private bool InEditMode(FlaggedEnum fieldSelectionChanges)
{
return Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary) || Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
}
private bool IsItemAdded(FlaggedEnum fieldSelectionChanges)
{
Coding.EnumHas(Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
}
private bool IsValidChange(FlaggedEnum fieldSelectionChanges)
{
return Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Order) ||
Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedCustomFieldItem) ||
Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.RemovedItem) ||
Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary) ||
Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
}
//Coding.cs
public static bool EnumHas(FieldSelectionChanges selectionChanges, FieldSelectionChanges valueToCheck)
{
return (selectionChanges & valueToCheck) == valueToCheck;
}
Well the part that is repetitive/somewhat ugly is the IF statements.
Suggest holding the result of those IF conditions in a boolean variable, and leverage that.
This code isnt complete, but you get the idea.
bool scenarioOne = Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedFieldItem);
bool scenarioTwo = Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Summary);
bool scenarioThree = Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.Order) || Coding.EnumHas(fieldSelectionChanges, FieldSelectionChanges.AddedCustomFieldItem) || Coding.EnumHas(fieldSelectionChanges,FieldSelectionChanges.RemovedItem);
if (scenarioOne || scenarioTwo)
StartEditMode();
if (scenarioOne) {
SetColumnDescriptorsToAdd(newFieldItemsSelected);
UpdateItems(selectedFieldItems);
}
else if (scenarioTwo || scenarioThree) {
UpdateItems(fieldItems);
}
if (scenarioOne || scenarioTwo || scenarioThree)
SetColumnsToShow();
Obviously, pick better names for the variable.
Or better yet, seperate out into seperate methods.
I would suggest extracting the three blocks into separate, well-named, methods. This will improve the readability if the UpdateFieldItems method. Since the three blocks are totally different, there is imo no way of consolidating these further.

A method that returns bool, but loads multiple objects

I have a simple method that returns bool, but it internally loads various objects.
I check for null for each, but it becomes very ugly.
Is there a better way?
public bool SomeTest(int id1)
{
bool result = false;
User user = userDao.GetById(id1);
if(user != null)
{
Blah blah = blahDao.GetById(user.BlahId);
if(blah != null)
{
FooBar fb = fbDao.GetById(blah.FooBarId);
if(fb != null)
{
// you_get_the_idea!
}
}
}
return result;
}
Is there a pattern that could make this a more inline instead of nested if's?
Does it need to do anything other than check whether the entity exists? I'll assume not.
First step: ignore the "one exit point" rule and reduce nesting:
public bool SomeTest(int id1)
{
User user = userDao.GetById(id1);
if (user == null)
{
return false;
}
Blah blah = blahDao.GetById(user.BlahId);
if (blah == null)
{
return false;
}
FooBar fb = fbDao.GetById(blah.FooBarId);
if (fb == null)
{
return false;
}
return true;
}
What comes next is likely to be language-specific... what language are you using, and which version of the platform? Can you alter your DAOs? C# has a bit more language flexibility (lambda expressions, the null coalescing operator, things like that) which may be handy in this situation.
Assuming there's nothing you can do to recover, you could just return as soon as you get a null:
User user = UserDAO.GetById(id1);
if(user == null) return false;
Blah blah = blahDao.GetById(user.BlahId);
if(blah == null) return false;
You might also want to look at the Null object pattern
seriously?
Blah blah = GetBlah();
if (blah == null) return false;
To add to all other answers, if you had an IDao interface for instance
public interface IDao
{
bool CanGetUser(int id);
}
Then you can pass in a List of DAO's created somewhere else.
public bool SomeTest(int id1, IEnumerable<IDao> daoList)
{
return daoList.Any( dao => dao.CanGetUser(id1) );
}
Perhaps:
User user;
Blah blah;
FooBar fb;
if( (user = userDao.GetById(id1)) != null
&& (blah = blahDao.GetById(user.BlahId)) != null
&& (fb = fbDao.GetById(blah.FooBarId)) != null)
{
// set flag, manipulate user/blah/fb, etc
}

How should I refactor a long chain of try-and-catch-wrapped speculative casting operations

I have some C# code that walks XML schemata using the Xml.Schema classes from the .NET framework. The various simple type restrictions are abstracted in the framework as a whole bunch of classes derived from Xml.Schema.XmlSchemaFacet. Unless there is something I've missed, the only way to know which of the derived facet types a given facet is, is to speculatively cast it to one of them, catching the resultant InvalidCastOperation in case of failure. Doing this leaves me with a really ugly function like this:
private void NavigateFacet(XmlSchemaFacet facet)
{
try
{
handler.Length((XmlSchemaLengthFacet)facet);
}
catch(InvalidCastException)
{
try
{
handler.MinLength((XmlSchemaMinLengthFacet)facet);
}
catch(InvalidCastException)
{
try
{
handler.MaxLength((XmlSchemaMaxLengthFacet)facet);
}
catch(InvalidCastException)
{
...
}
}
}
}
I assume there must be more elegant ways to do this; either using some property I've missed from the .NET framework, or with some clever piece of OO trickery. Can anyone enlighten me?
Because I prefer debugging data to debugging code, I'd do it like this, especially if the code had to handle all of the XmlSchemaFacet subclasses:
Dictionary<Type, Action<XmlSchemaFacet>> HandlerMap =
new Dictionary<Type, Action<XmlSchemaFacet>>
{
{typeof(XmlSchemaLengthFacet), handler.Length},
{typeof(XmlSchemaMinLengthFacet), handler.MinLength},
{typeof(XmlSchemaMaxLengthFacet), handler.MaxLength}
};
HandlerMap[facet.GetType()](facet);
This'll throw a KeyNotFoundException if facet isn't of a known type. Note that all of the handler methods will have to cast their argument from XmlSchemaFacet, so you're probably not saving on total lines of code, but you're definitely saving on the number of paths through your code.
There also comes a point where (assuming that the map is pre-built) mapping types to methods with a dictionary will be faster than traversing a linear list of types, which is essentially what using a bunch of if blocks gets you.
You can try using the as keyword. Some others have recommended using the is keyword instead. I found this to be a great explanation of why as is better.
Some sample code:
private void NavigateFacet(XmlSchemaFacet facet)
{
XmlSchemaLengthFacet lengthFacet = facet as XmlSchemaLengthFacet;
if (lengthFacet != null)
{
handler.Length(lengthFacet);
}
else
{
// Re-try with XmlSchemaMinLengthFacet, etc.
}
}
private void NavigateFacet(XmlSchemaFacet facet)
{
if (facet is XmlSchemaLengthFacet)
{
handler.Length((XmlSchemaLengthFacet)facet);
}
else if (facet is XmlSchemaMinLengthFacet)
{
handler.MinLength((XmlSchemaMinLengthFacet)facet);
}
else if (facet is XmlSchemaMaxLengthFacet)
{
handler.MinLength((XmlSchemaMaxLengthFacet)facet);
}
// etc.
}
Update: I decided to benchmark the different methods discussed here (is vs. as). Here is the code that I used:
object c1 = new Class1();
int trials = 10000000;
Class1 tester;
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i < trials; i++)
{
if (c1 is Class1)
{
tester = (Class1)c1;
}
}
watch.Stop();
MessageBox.Show(watch.ElapsedMilliseconds.ToString()); // ~104 ms
watch.Reset();
watch.Start();
for (int i = 0; i < trials; i++)
{
tester = c1 as Class1;
if (tester != null)
{
//
}
}
watch.Stop();
MessageBox.Show(watch.ElapsedMilliseconds.ToString()); // ~86 ms
watch.Reset();
watch.Start();
for (int i = 0; i < trials; i++)
{
if (c1 is Class1)
{
//
}
}
watch.Stop();
MessageBox.Show(watch.ElapsedMilliseconds.ToString()); // ~74 ms
watch.Reset();
watch.Start();
for (int i = 0; i < trials; i++)
{
//
}
watch.Stop();
MessageBox.Show(watch.ElapsedMilliseconds.ToString()); // ~50 ms
As expected, using the as keyword and then checking for null is faster than using the is keyword and casting (36 ms vs. 54 ms, subtracting the cost of the loop itself).
However, using the is keyword and then not casting is faster still (24ms), which means that finding the correct type with a series of is checks and then only casting once when the correct type is identified could actually be faster (depending upon the number of different type checks that have to be done in this method before the correct type is identified).
The deeper point, however, is that the number of trials in this test is 10 million, which means it really doesn't make much difference which method you use. Using is and casting takes 0.0000054 milliseconds, while using as and checking for null takes 0.0000036 milliseconds (on my ancient notebook).
You could try using the as keyword - if the cast fails, you get a null instead of an exception.
private void NavigateFacet(XmlSchemaFacet facet)
{
var length = facet as XmlSchemaLengthFacet;
if (length != null)
{
handler.Length(length);
return;
}
var minlength = facet as XmlSchemaMinLengthFacet;
if (minlength != null)
{
handler.MinLength(minlength);
return;
}
var maxlength = facet as XmlSchemaMaxLengthFacet;
if (maxlength != null)
{
handler.MaxLength(maxlength);
return;
}
...
}
If you had control over the classes, I'd suggest using a variant of the Visitor pattern (aka Double Despatch to recover the type information more cleanly, but since you don't, this is one relatively simple approach.
Update: Using the variable to store the result of the as cast avoids the need to go through the type checking logic twice.
Update 2: When C# 4 becomes available, you'll be able to use dynamic to do the dispatching for you:
public class HandlerDemo
{
public void Handle(XmlSchemaLengthFacet facet) { ... }
public void Handle(XmlSchemaMinLengthFacet facet) { ... }
public void Handle(XmlSchemaMaxLengthFacet facet) { ... }
...
}
private void NavigateFacet(XmlSchemaFacet facet)
{
dynamic handler = new HandlerDemo();
handler.Handle(facet);
}
This will work because method dispatch on dynamic objects uses the same rules as normal method overriding, but evaluated at run-time instead of compile-time.
Under the hood, the Dynamic Language Runtime (DLR) will be doing much the same kind of trick as the code shown in this (and other answers), but with the addition of caching for performance.
This is a proper way to do this without any try-catches.
if (facet is XmlSchemaLengthFacet)
{
handler.Length((XmlSchemaLengthFacet)facet);
}
else if (facet is XmlSchemaMinLengthFacet)
{
handler.MinLength((XmlSchemaMinLengthFacet)facet);
}
else if (facet is XmlSchemaMaxLengthFacet)
{
handler.MaxLength((XmlSchemaMaxLengthFacet)facet);
}
else
{
//Handle Error
}
use "is" to determine whether an object is of a given type
use "as" for type conversion, it is faster than normal casting and won't throw exceptions, it reuturns null on error instead
You can do it like this:
private void NavigateFacet(XmlSchemaFacet facet)
{
if (facet is XmlSchemaLengthFacet)
{
handler.Length(facet as XmlSchemaLengthFacet);
}
else if (facet is XmlSchemaMinLengthFacet)
{
handler.MinLength(facet as XmlSchemaMinLengthFacet);
}
else if (facet is XmlSchemaMaxLengthFacet)
{
handler.MaxLength(facet as XmlSchemaMaxLengthFacet);
}
}

Categories