0
Completed

How to avoid nested if condition?

mahendrag gajera 4 years ago updated by Alexander Shvets 4 years ago 7

Hello Sir,

Please look the below code and suggest me the best way to avoid this kind of condition.

if (obj.Attributes[PropertyName.Name.ToString()].Equals(objToFind.Attributes[PropertyName.Name.ToString()])){

if (obj.Attributes[PropertyName.Role.ToString()].Equals(objToFind.Attributes[PropertyName.Role.ToString()])){

if (obj.Attributes[PropertyName.Value.ToString()].Equals(objToFind.Attributes[PropertyName.Value.ToString()])){

if (obj.Attributes[PropertyName.Class.ToString()].Equals(objToFind.Attributes[PropertyName.Class.ToString()])){

if (obj.Attributes[PropertyName.Top.ToString()].Equals(objToFind.Attributes[PropertyName.Top.ToString()])){

if (obj.Attributes[PropertyName.Left.ToString()].Equals(objToFind.Attributes[PropertyName.Left.ToString()])){

if (obj.Attributes[PropertyName.Height.ToString()].Equals(objToFind.Attributes[PropertyName.Height.ToString()])){

if (obj.Attributes[PropertyName.Width.ToString()].Equals(objToFind.Attributes[PropertyName.Width.ToString()]))

{

//some operation

}


Thanks

Mahendra

Answer

Answer

Sorry, C# is not my "native" programming language, but as far as I know, C# has almost the same reflection capabilities as Java. It should be easy to convert the code above to C# by looking at examples at MSDN:

https://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo.getvalue(v=vs.110).aspx

for instance:

PropertyName.class.getField(fieldName) will become typeof(PropertyName).GetField(fieldName). And attributeField.get(PropertyName).toString() will probably become attribute.getValue(PropertyName). Check the MSDN article for the list of exceptions you need to handle while doing this.


GOOD, I'M SATISFIED

Great answer i have never thought of it.Can you explain in C#?

Satisfaction mark by mahendrag gajera 4 years ago
Completed

I would try to extract a new private method or local function for comparing fields by names.


Assuming your example was in Java, I would aim for something like this:


    public void someBusinessLogicMethod() {
        // Define and intialize obj, objToFind, PropertyName
        // ...
        String[] fieldsToCompare = ["Name", "Role", "Value", "Class", "Top", "Left", "Height", "Width"];
        if (this.compareGivenFields(obj, objToFind, PropertyName, fieldsToCompare)) {
           // Some code.
        }
    }
    private Boolean compareGivenFields(Object obj, Object objToFind, Object PropertyName, String[] fieldNames) {
        Boolean result = false;
        for (String fieldName : fieldNames) {
            result &= compareField(obj, objToFind, PropertyName, fieldName);
        }
        return result;
    }
    private Boolean compareField(Object obj, Object objToFind, Object PropertyName, String fieldName) {
        try {
            Field attributeField = PropertyName.class.getField(fieldName);
            try {
                String attribute = attributeField.get(PropertyName).toString();
                return obj.Attributes[attribute].Equals(objToFind.Attributes[attribute]);
            } catch (IllegalAccessException e) {
                System.out.println("Error accessing field value.");
            }
        } catch(NoSuchFieldException e) {
            System.out.println("There's no such field.");
        }
        return false;
    }


In other languages which support direct field access by name (PHP, Javascript) solution might be even simpler.

By the way, you're right if you think that we created more code than we saved. Sometimes it's better to just leave things the way the are.


However, that is the solution for growing number of sub-ifs. You can easily put more fields to compare, but the nesting level won't change.

Answer

Sorry, C# is not my "native" programming language, but as far as I know, C# has almost the same reflection capabilities as Java. It should be easy to convert the code above to C# by looking at examples at MSDN:

https://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo.getvalue(v=vs.110).aspx

for instance:

PropertyName.class.getField(fieldName) will become typeof(PropertyName).GetField(fieldName). And attributeField.get(PropertyName).toString() will probably become attribute.getValue(PropertyName). Check the MSDN article for the list of exceptions you need to handle while doing this.


Thanks for reply.

Are you suggesting refection for this ifelse.

The reflection has own cost for performance.

Is it ok?

As with all things in programming you have to balance performance cost with with any benefit gained. But I'd say if you're not running this code in a loop, don't worry about the performance.

Would you favor me, why it would be bother when it runs from loop?

Here's analogy: you work on the 20th floor, but the dining room is on 3rd floor. It's fine to take a 2-minute elevator ride once a day on a lunch break. However, if the only coffee machine is also there, you will have to spend hours riding back and forth each time you commit your code.


Jokes aside, here are 2 stackoverflow threads, where you can get in-depth answer:

http://stackoverflow.com/questions/224232/what-is-the-cost-of-net-reflection

http://stackoverflow.com/questions/25458/how-costly-is-net-reflection