How could I simplify this long chain of conditional statements?












0















I have the following enum



[Flags]
internal enum DataSectionFlags : uint
{
TypeReg = 0x0,
TypeDsect = 0x01,
TypeNoLoad = 0x02,
TypeGroup = 0x04,
TypeNoPadded = 0x08,
TypeCopy = 0x010,

ContentCode = 0x020,
ContentInitializedData = 0x040,
ContentUninitializedData = 0x080,

LinkOther = 0x0100,
LinkInfo = 0x0200,

TypeOver = 0x0400,

LinkRemove = 0x0800,
LinkComDat = 0x01000,

NoDeferSpecExceptions = 0x04000,

RelativeGP = 0x08000,

MemPurgeable = 0x020000,

Memory16Bit = 0x020000,
MemoryLocked = 0x040000,
MemoryPreload = 0x080000,

Align1Bytes = 0x0100000,
Align2Bytes = 0x0200000,
Align4Bytes = 0x0300000,
Align8Bytes = 0x0400000,
Align16Bytes = 0x0500000,
Align32Bytes = 0x0600000,
Align64Bytes = 0x0700000,
Align128Bytes = 0x0800000,
Align256Bytes = 0x0900000,
Align512Bytes = 0x0A00000,
Align1024Bytes = 0x0B00000,
Align2048Bytes = 0x0C00000,
Align4096Bytes = 0x0D00000,
Align8192Bytes = 0x0E00000,

LinkExtendedRelocationOverflow = 0x01000000,

MemoryDiscardable = 0x02000000,
MemoryNotCached = 0x04000000,
MemoryNotPaged = 0x08000000,
MemoryShared = 0x10000000,
MemoryExecute = 0x20000000,
MemoryRead = 0x40000000,
MemoryWrite = 0x80000000
}


I am casting a uint variable with this enum like so



var testVariable = (DataSectionFlags) 1610612768;


I have a method that processes the above variable like this



private static uint GetSectionProtection(DataSectionFlags characteristics)
{
uint result = 0;

if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
{
// PageNoCache

result |= 0x200;
}

if (characteristics.HasFlag(DataSectionFlags.MemoryExecute))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteReadWrite

result |= 0x40;
}

else
{
// PageExecuteRead

result |= 0x20;
}

}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteWriteCopy

result |= 0x80;
}

else
{
// PageExecute

result |= 0x10;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageReadWrite

result |= 0x04;
}

else
{
// PageReadOnly

result |= 0x02;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageWriteCopy

result |= 0x08;
}

else
{
// PageNoAccess

result |= 0x01;
}

return result;
}


I'm attempting to simplify the long chain of conditional statements inside this method but am having trouble doing so.



What would be the simplest way to write the conditional statements inside the method whilst still maintaining their functionality?










share|improve this question


















  • 3





    This code is pretty easy to follow. Not sure it needs to change. Shorter does not necessarily mean simpler. In fact, terse code with lots going on can be more confusing for others (or your future self) to maintain.

    – Daniel
    Nov 21 '18 at 1:40











  • I see. I just thought it was bad convention to have so many nested statements

    – user10454073
    Nov 21 '18 at 1:45











  • i agree with @Daniel, there's no problem with your code. as long as it is easy to understand

    – gadasadox
    Nov 21 '18 at 2:08








  • 2





    One of the easiest ways you can make this code more readable is to ask yourself every time you write a comment "how could I have avoided writing this comment?" If you had const uint PageNoCache = 0x200; in your class , then the first line of your method is if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached)) result |= PageNoCache; and now you don't need a comment.

    – Eric Lippert
    Nov 21 '18 at 3:07
















0















I have the following enum



[Flags]
internal enum DataSectionFlags : uint
{
TypeReg = 0x0,
TypeDsect = 0x01,
TypeNoLoad = 0x02,
TypeGroup = 0x04,
TypeNoPadded = 0x08,
TypeCopy = 0x010,

ContentCode = 0x020,
ContentInitializedData = 0x040,
ContentUninitializedData = 0x080,

LinkOther = 0x0100,
LinkInfo = 0x0200,

TypeOver = 0x0400,

LinkRemove = 0x0800,
LinkComDat = 0x01000,

NoDeferSpecExceptions = 0x04000,

RelativeGP = 0x08000,

MemPurgeable = 0x020000,

Memory16Bit = 0x020000,
MemoryLocked = 0x040000,
MemoryPreload = 0x080000,

Align1Bytes = 0x0100000,
Align2Bytes = 0x0200000,
Align4Bytes = 0x0300000,
Align8Bytes = 0x0400000,
Align16Bytes = 0x0500000,
Align32Bytes = 0x0600000,
Align64Bytes = 0x0700000,
Align128Bytes = 0x0800000,
Align256Bytes = 0x0900000,
Align512Bytes = 0x0A00000,
Align1024Bytes = 0x0B00000,
Align2048Bytes = 0x0C00000,
Align4096Bytes = 0x0D00000,
Align8192Bytes = 0x0E00000,

LinkExtendedRelocationOverflow = 0x01000000,

MemoryDiscardable = 0x02000000,
MemoryNotCached = 0x04000000,
MemoryNotPaged = 0x08000000,
MemoryShared = 0x10000000,
MemoryExecute = 0x20000000,
MemoryRead = 0x40000000,
MemoryWrite = 0x80000000
}


I am casting a uint variable with this enum like so



var testVariable = (DataSectionFlags) 1610612768;


I have a method that processes the above variable like this



private static uint GetSectionProtection(DataSectionFlags characteristics)
{
uint result = 0;

if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
{
// PageNoCache

result |= 0x200;
}

if (characteristics.HasFlag(DataSectionFlags.MemoryExecute))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteReadWrite

result |= 0x40;
}

else
{
// PageExecuteRead

result |= 0x20;
}

}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteWriteCopy

result |= 0x80;
}

else
{
// PageExecute

result |= 0x10;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageReadWrite

result |= 0x04;
}

else
{
// PageReadOnly

result |= 0x02;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageWriteCopy

result |= 0x08;
}

else
{
// PageNoAccess

result |= 0x01;
}

return result;
}


I'm attempting to simplify the long chain of conditional statements inside this method but am having trouble doing so.



What would be the simplest way to write the conditional statements inside the method whilst still maintaining their functionality?










share|improve this question


















  • 3





    This code is pretty easy to follow. Not sure it needs to change. Shorter does not necessarily mean simpler. In fact, terse code with lots going on can be more confusing for others (or your future self) to maintain.

    – Daniel
    Nov 21 '18 at 1:40











  • I see. I just thought it was bad convention to have so many nested statements

    – user10454073
    Nov 21 '18 at 1:45











  • i agree with @Daniel, there's no problem with your code. as long as it is easy to understand

    – gadasadox
    Nov 21 '18 at 2:08








  • 2





    One of the easiest ways you can make this code more readable is to ask yourself every time you write a comment "how could I have avoided writing this comment?" If you had const uint PageNoCache = 0x200; in your class , then the first line of your method is if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached)) result |= PageNoCache; and now you don't need a comment.

    – Eric Lippert
    Nov 21 '18 at 3:07














0












0








0


0






I have the following enum



[Flags]
internal enum DataSectionFlags : uint
{
TypeReg = 0x0,
TypeDsect = 0x01,
TypeNoLoad = 0x02,
TypeGroup = 0x04,
TypeNoPadded = 0x08,
TypeCopy = 0x010,

ContentCode = 0x020,
ContentInitializedData = 0x040,
ContentUninitializedData = 0x080,

LinkOther = 0x0100,
LinkInfo = 0x0200,

TypeOver = 0x0400,

LinkRemove = 0x0800,
LinkComDat = 0x01000,

NoDeferSpecExceptions = 0x04000,

RelativeGP = 0x08000,

MemPurgeable = 0x020000,

Memory16Bit = 0x020000,
MemoryLocked = 0x040000,
MemoryPreload = 0x080000,

Align1Bytes = 0x0100000,
Align2Bytes = 0x0200000,
Align4Bytes = 0x0300000,
Align8Bytes = 0x0400000,
Align16Bytes = 0x0500000,
Align32Bytes = 0x0600000,
Align64Bytes = 0x0700000,
Align128Bytes = 0x0800000,
Align256Bytes = 0x0900000,
Align512Bytes = 0x0A00000,
Align1024Bytes = 0x0B00000,
Align2048Bytes = 0x0C00000,
Align4096Bytes = 0x0D00000,
Align8192Bytes = 0x0E00000,

LinkExtendedRelocationOverflow = 0x01000000,

MemoryDiscardable = 0x02000000,
MemoryNotCached = 0x04000000,
MemoryNotPaged = 0x08000000,
MemoryShared = 0x10000000,
MemoryExecute = 0x20000000,
MemoryRead = 0x40000000,
MemoryWrite = 0x80000000
}


I am casting a uint variable with this enum like so



var testVariable = (DataSectionFlags) 1610612768;


I have a method that processes the above variable like this



private static uint GetSectionProtection(DataSectionFlags characteristics)
{
uint result = 0;

if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
{
// PageNoCache

result |= 0x200;
}

if (characteristics.HasFlag(DataSectionFlags.MemoryExecute))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteReadWrite

result |= 0x40;
}

else
{
// PageExecuteRead

result |= 0x20;
}

}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteWriteCopy

result |= 0x80;
}

else
{
// PageExecute

result |= 0x10;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageReadWrite

result |= 0x04;
}

else
{
// PageReadOnly

result |= 0x02;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageWriteCopy

result |= 0x08;
}

else
{
// PageNoAccess

result |= 0x01;
}

return result;
}


I'm attempting to simplify the long chain of conditional statements inside this method but am having trouble doing so.



What would be the simplest way to write the conditional statements inside the method whilst still maintaining their functionality?










share|improve this question














I have the following enum



[Flags]
internal enum DataSectionFlags : uint
{
TypeReg = 0x0,
TypeDsect = 0x01,
TypeNoLoad = 0x02,
TypeGroup = 0x04,
TypeNoPadded = 0x08,
TypeCopy = 0x010,

ContentCode = 0x020,
ContentInitializedData = 0x040,
ContentUninitializedData = 0x080,

LinkOther = 0x0100,
LinkInfo = 0x0200,

TypeOver = 0x0400,

LinkRemove = 0x0800,
LinkComDat = 0x01000,

NoDeferSpecExceptions = 0x04000,

RelativeGP = 0x08000,

MemPurgeable = 0x020000,

Memory16Bit = 0x020000,
MemoryLocked = 0x040000,
MemoryPreload = 0x080000,

Align1Bytes = 0x0100000,
Align2Bytes = 0x0200000,
Align4Bytes = 0x0300000,
Align8Bytes = 0x0400000,
Align16Bytes = 0x0500000,
Align32Bytes = 0x0600000,
Align64Bytes = 0x0700000,
Align128Bytes = 0x0800000,
Align256Bytes = 0x0900000,
Align512Bytes = 0x0A00000,
Align1024Bytes = 0x0B00000,
Align2048Bytes = 0x0C00000,
Align4096Bytes = 0x0D00000,
Align8192Bytes = 0x0E00000,

LinkExtendedRelocationOverflow = 0x01000000,

MemoryDiscardable = 0x02000000,
MemoryNotCached = 0x04000000,
MemoryNotPaged = 0x08000000,
MemoryShared = 0x10000000,
MemoryExecute = 0x20000000,
MemoryRead = 0x40000000,
MemoryWrite = 0x80000000
}


I am casting a uint variable with this enum like so



var testVariable = (DataSectionFlags) 1610612768;


I have a method that processes the above variable like this



private static uint GetSectionProtection(DataSectionFlags characteristics)
{
uint result = 0;

if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
{
// PageNoCache

result |= 0x200;
}

if (characteristics.HasFlag(DataSectionFlags.MemoryExecute))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteReadWrite

result |= 0x40;
}

else
{
// PageExecuteRead

result |= 0x20;
}

}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageExecuteWriteCopy

result |= 0x80;
}

else
{
// PageExecute

result |= 0x10;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryRead))
{
if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageReadWrite

result |= 0x04;
}

else
{
// PageReadOnly

result |= 0x02;
}
}

else if (characteristics.HasFlag(DataSectionFlags.MemoryWrite))
{
// PageWriteCopy

result |= 0x08;
}

else
{
// PageNoAccess

result |= 0x01;
}

return result;
}


I'm attempting to simplify the long chain of conditional statements inside this method but am having trouble doing so.



What would be the simplest way to write the conditional statements inside the method whilst still maintaining their functionality?







c# performance if-statement






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 '18 at 1:36







user10454073















  • 3





    This code is pretty easy to follow. Not sure it needs to change. Shorter does not necessarily mean simpler. In fact, terse code with lots going on can be more confusing for others (or your future self) to maintain.

    – Daniel
    Nov 21 '18 at 1:40











  • I see. I just thought it was bad convention to have so many nested statements

    – user10454073
    Nov 21 '18 at 1:45











  • i agree with @Daniel, there's no problem with your code. as long as it is easy to understand

    – gadasadox
    Nov 21 '18 at 2:08








  • 2





    One of the easiest ways you can make this code more readable is to ask yourself every time you write a comment "how could I have avoided writing this comment?" If you had const uint PageNoCache = 0x200; in your class , then the first line of your method is if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached)) result |= PageNoCache; and now you don't need a comment.

    – Eric Lippert
    Nov 21 '18 at 3:07














  • 3





    This code is pretty easy to follow. Not sure it needs to change. Shorter does not necessarily mean simpler. In fact, terse code with lots going on can be more confusing for others (or your future self) to maintain.

    – Daniel
    Nov 21 '18 at 1:40











  • I see. I just thought it was bad convention to have so many nested statements

    – user10454073
    Nov 21 '18 at 1:45











  • i agree with @Daniel, there's no problem with your code. as long as it is easy to understand

    – gadasadox
    Nov 21 '18 at 2:08








  • 2





    One of the easiest ways you can make this code more readable is to ask yourself every time you write a comment "how could I have avoided writing this comment?" If you had const uint PageNoCache = 0x200; in your class , then the first line of your method is if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached)) result |= PageNoCache; and now you don't need a comment.

    – Eric Lippert
    Nov 21 '18 at 3:07








3




3





This code is pretty easy to follow. Not sure it needs to change. Shorter does not necessarily mean simpler. In fact, terse code with lots going on can be more confusing for others (or your future self) to maintain.

– Daniel
Nov 21 '18 at 1:40





This code is pretty easy to follow. Not sure it needs to change. Shorter does not necessarily mean simpler. In fact, terse code with lots going on can be more confusing for others (or your future self) to maintain.

– Daniel
Nov 21 '18 at 1:40













I see. I just thought it was bad convention to have so many nested statements

– user10454073
Nov 21 '18 at 1:45





I see. I just thought it was bad convention to have so many nested statements

– user10454073
Nov 21 '18 at 1:45













i agree with @Daniel, there's no problem with your code. as long as it is easy to understand

– gadasadox
Nov 21 '18 at 2:08







i agree with @Daniel, there's no problem with your code. as long as it is easy to understand

– gadasadox
Nov 21 '18 at 2:08






2




2





One of the easiest ways you can make this code more readable is to ask yourself every time you write a comment "how could I have avoided writing this comment?" If you had const uint PageNoCache = 0x200; in your class , then the first line of your method is if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached)) result |= PageNoCache; and now you don't need a comment.

– Eric Lippert
Nov 21 '18 at 3:07





One of the easiest ways you can make this code more readable is to ask yourself every time you write a comment "how could I have avoided writing this comment?" If you had const uint PageNoCache = 0x200; in your class , then the first line of your method is if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached)) result |= PageNoCache; and now you don't need a comment.

– Eric Lippert
Nov 21 '18 at 3:07












2 Answers
2






active

oldest

votes


















4














I suggest a lookup dictionary like:



var sectionProtection = new Dictionary<DataSectionFlags, uint>
{
[DataSectionFlags.TypeReg ] = 1,
[DataSectionFlags.TypeDsect ] = 2,
...
[DataSectionFlags.MemoryExecute | DataSectionFlags.MemoryRead | DataSectionFlags.MemoryWrite] = 0x40,
...
};


Note you'll need a separate entry for every combination of flags. Given such, you can then replace your function with the statement



var testVariable = sectionProtection[(DataSectionFlags) 1610612768];


or, if not every combination is defined:



if (sectionProtection.TryGetValue((DataSectionFlags) 1610612768, out testVariable ))


I consider this not only simpler to understand, faster to run, but also more correct. It is too easy to miss a combination, to have the same combination return different values, or to include the same combination twice when creating a list of if ... else if ... else if ... statements. If you miss a combination in a lookup dictionary you get an exception (or TryGetValue returns false). If you add the same combination to a dictionary twice you get an error.






share|improve this answer

































    1














    This is the best that I could come up with at short notice:



    private static uint GetSectionProtection(DataSectionFlags characteristics)
    {
    uint result = 0;

    if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
    {
    // PageNoCache
    result |= 0x200;
    }

    var ladder = new KeyValuePair<DataSectionFlags, uint>
    {
    new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x40),
    new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, 0x20),
    new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, 0x80),
    new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, }, 0x10),
    new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x04),
    new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, }, 0x02),
    new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryWrite, }, 0x08),
    new KeyValuePair<DataSectionFlags, uint>(new DataSectionFlags { }, 0x01),
    };

    result |= ladder.Where(x => x.Key.All(y => characteristics.HasFlag(y))).First().Value;

    return result;
    }




    A possibly more readable version:



    private static uint GetSectionProtection(DataSectionFlags characteristics)
    {
    uint result = 0;

    if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
    {
    // PageNoCache
    result |= 0x200;
    }

    var ladder = new
    {
    new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x40 },
    new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, Value = (uint)0x20 },
    new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, Value = (uint)0x80 },
    new { Flags = new { DataSectionFlags.MemoryExecute, }, Value = (uint)0x10 },
    new { Flags = new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x04 },
    new { Flags = new { DataSectionFlags.MemoryRead, }, Value = (uint)0x02 },
    new { Flags = new { DataSectionFlags.MemoryWrite, }, Value = (uint)0x08 },
    new { Flags = new DataSectionFlags { }, Value = (uint)0x01 },
    };

    result |= ladder.Where(x => x.Flags.All(y => characteristics.HasFlag(y))).First().Value;

    return result;
    }





    share|improve this answer





















    • 4





      Clever, but I find the original significantly more clear and readable (and thus maintainable)...

      – TypeIA
      Nov 21 '18 at 2:02






    • 1





      @TypeIA - Yes, I agree. What makes this interesting is that this is configurable. The ladder can be changed at run-time or read from a config file. But I do agree that it's not as easy to follow.

      – Enigmativity
      Nov 21 '18 at 2:38






    • 1





      This is more maintainable. The KVP instantiations is a data structure that clearly associates flags; no triple nested if's needed! Comparatively, data structure always results in simpler code: 9 "result =" blocks collapse to 1 line! Modifying that if-else/if nest requires more mental energy and is necessarily more error prone than non-branching code. A 1-line comment will explain what uint (the value in the KV pair) is; this is an understandability issue, not readability. This answer is pleasantly readable vis-a-vis a nested control structure.

      – radarbob
      Nov 21 '18 at 3:40













    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404118%2fhow-could-i-simplify-this-long-chain-of-conditional-statements%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown
























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    I suggest a lookup dictionary like:



    var sectionProtection = new Dictionary<DataSectionFlags, uint>
    {
    [DataSectionFlags.TypeReg ] = 1,
    [DataSectionFlags.TypeDsect ] = 2,
    ...
    [DataSectionFlags.MemoryExecute | DataSectionFlags.MemoryRead | DataSectionFlags.MemoryWrite] = 0x40,
    ...
    };


    Note you'll need a separate entry for every combination of flags. Given such, you can then replace your function with the statement



    var testVariable = sectionProtection[(DataSectionFlags) 1610612768];


    or, if not every combination is defined:



    if (sectionProtection.TryGetValue((DataSectionFlags) 1610612768, out testVariable ))


    I consider this not only simpler to understand, faster to run, but also more correct. It is too easy to miss a combination, to have the same combination return different values, or to include the same combination twice when creating a list of if ... else if ... else if ... statements. If you miss a combination in a lookup dictionary you get an exception (or TryGetValue returns false). If you add the same combination to a dictionary twice you get an error.






    share|improve this answer






























      4














      I suggest a lookup dictionary like:



      var sectionProtection = new Dictionary<DataSectionFlags, uint>
      {
      [DataSectionFlags.TypeReg ] = 1,
      [DataSectionFlags.TypeDsect ] = 2,
      ...
      [DataSectionFlags.MemoryExecute | DataSectionFlags.MemoryRead | DataSectionFlags.MemoryWrite] = 0x40,
      ...
      };


      Note you'll need a separate entry for every combination of flags. Given such, you can then replace your function with the statement



      var testVariable = sectionProtection[(DataSectionFlags) 1610612768];


      or, if not every combination is defined:



      if (sectionProtection.TryGetValue((DataSectionFlags) 1610612768, out testVariable ))


      I consider this not only simpler to understand, faster to run, but also more correct. It is too easy to miss a combination, to have the same combination return different values, or to include the same combination twice when creating a list of if ... else if ... else if ... statements. If you miss a combination in a lookup dictionary you get an exception (or TryGetValue returns false). If you add the same combination to a dictionary twice you get an error.






      share|improve this answer




























        4












        4








        4







        I suggest a lookup dictionary like:



        var sectionProtection = new Dictionary<DataSectionFlags, uint>
        {
        [DataSectionFlags.TypeReg ] = 1,
        [DataSectionFlags.TypeDsect ] = 2,
        ...
        [DataSectionFlags.MemoryExecute | DataSectionFlags.MemoryRead | DataSectionFlags.MemoryWrite] = 0x40,
        ...
        };


        Note you'll need a separate entry for every combination of flags. Given such, you can then replace your function with the statement



        var testVariable = sectionProtection[(DataSectionFlags) 1610612768];


        or, if not every combination is defined:



        if (sectionProtection.TryGetValue((DataSectionFlags) 1610612768, out testVariable ))


        I consider this not only simpler to understand, faster to run, but also more correct. It is too easy to miss a combination, to have the same combination return different values, or to include the same combination twice when creating a list of if ... else if ... else if ... statements. If you miss a combination in a lookup dictionary you get an exception (or TryGetValue returns false). If you add the same combination to a dictionary twice you get an error.






        share|improve this answer















        I suggest a lookup dictionary like:



        var sectionProtection = new Dictionary<DataSectionFlags, uint>
        {
        [DataSectionFlags.TypeReg ] = 1,
        [DataSectionFlags.TypeDsect ] = 2,
        ...
        [DataSectionFlags.MemoryExecute | DataSectionFlags.MemoryRead | DataSectionFlags.MemoryWrite] = 0x40,
        ...
        };


        Note you'll need a separate entry for every combination of flags. Given such, you can then replace your function with the statement



        var testVariable = sectionProtection[(DataSectionFlags) 1610612768];


        or, if not every combination is defined:



        if (sectionProtection.TryGetValue((DataSectionFlags) 1610612768, out testVariable ))


        I consider this not only simpler to understand, faster to run, but also more correct. It is too easy to miss a combination, to have the same combination return different values, or to include the same combination twice when creating a list of if ... else if ... else if ... statements. If you miss a combination in a lookup dictionary you get an exception (or TryGetValue returns false). If you add the same combination to a dictionary twice you get an error.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 26 '18 at 19:37

























        answered Nov 21 '18 at 1:57









        Dour High ArchDour High Arch

        18.1k166679




        18.1k166679

























            1














            This is the best that I could come up with at short notice:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new KeyValuePair<DataSectionFlags, uint>
            {
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x40),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, 0x20),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, 0x80),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, }, 0x10),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x04),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, }, 0x02),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryWrite, }, 0x08),
            new KeyValuePair<DataSectionFlags, uint>(new DataSectionFlags { }, 0x01),
            };

            result |= ladder.Where(x => x.Key.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }




            A possibly more readable version:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new
            {
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x40 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, Value = (uint)0x20 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, Value = (uint)0x80 },
            new { Flags = new { DataSectionFlags.MemoryExecute, }, Value = (uint)0x10 },
            new { Flags = new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x04 },
            new { Flags = new { DataSectionFlags.MemoryRead, }, Value = (uint)0x02 },
            new { Flags = new { DataSectionFlags.MemoryWrite, }, Value = (uint)0x08 },
            new { Flags = new DataSectionFlags { }, Value = (uint)0x01 },
            };

            result |= ladder.Where(x => x.Flags.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }





            share|improve this answer





















            • 4





              Clever, but I find the original significantly more clear and readable (and thus maintainable)...

              – TypeIA
              Nov 21 '18 at 2:02






            • 1





              @TypeIA - Yes, I agree. What makes this interesting is that this is configurable. The ladder can be changed at run-time or read from a config file. But I do agree that it's not as easy to follow.

              – Enigmativity
              Nov 21 '18 at 2:38






            • 1





              This is more maintainable. The KVP instantiations is a data structure that clearly associates flags; no triple nested if's needed! Comparatively, data structure always results in simpler code: 9 "result =" blocks collapse to 1 line! Modifying that if-else/if nest requires more mental energy and is necessarily more error prone than non-branching code. A 1-line comment will explain what uint (the value in the KV pair) is; this is an understandability issue, not readability. This answer is pleasantly readable vis-a-vis a nested control structure.

              – radarbob
              Nov 21 '18 at 3:40


















            1














            This is the best that I could come up with at short notice:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new KeyValuePair<DataSectionFlags, uint>
            {
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x40),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, 0x20),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, 0x80),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, }, 0x10),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x04),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, }, 0x02),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryWrite, }, 0x08),
            new KeyValuePair<DataSectionFlags, uint>(new DataSectionFlags { }, 0x01),
            };

            result |= ladder.Where(x => x.Key.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }




            A possibly more readable version:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new
            {
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x40 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, Value = (uint)0x20 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, Value = (uint)0x80 },
            new { Flags = new { DataSectionFlags.MemoryExecute, }, Value = (uint)0x10 },
            new { Flags = new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x04 },
            new { Flags = new { DataSectionFlags.MemoryRead, }, Value = (uint)0x02 },
            new { Flags = new { DataSectionFlags.MemoryWrite, }, Value = (uint)0x08 },
            new { Flags = new DataSectionFlags { }, Value = (uint)0x01 },
            };

            result |= ladder.Where(x => x.Flags.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }





            share|improve this answer





















            • 4





              Clever, but I find the original significantly more clear and readable (and thus maintainable)...

              – TypeIA
              Nov 21 '18 at 2:02






            • 1





              @TypeIA - Yes, I agree. What makes this interesting is that this is configurable. The ladder can be changed at run-time or read from a config file. But I do agree that it's not as easy to follow.

              – Enigmativity
              Nov 21 '18 at 2:38






            • 1





              This is more maintainable. The KVP instantiations is a data structure that clearly associates flags; no triple nested if's needed! Comparatively, data structure always results in simpler code: 9 "result =" blocks collapse to 1 line! Modifying that if-else/if nest requires more mental energy and is necessarily more error prone than non-branching code. A 1-line comment will explain what uint (the value in the KV pair) is; this is an understandability issue, not readability. This answer is pleasantly readable vis-a-vis a nested control structure.

              – radarbob
              Nov 21 '18 at 3:40
















            1












            1








            1







            This is the best that I could come up with at short notice:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new KeyValuePair<DataSectionFlags, uint>
            {
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x40),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, 0x20),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, 0x80),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, }, 0x10),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x04),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, }, 0x02),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryWrite, }, 0x08),
            new KeyValuePair<DataSectionFlags, uint>(new DataSectionFlags { }, 0x01),
            };

            result |= ladder.Where(x => x.Key.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }




            A possibly more readable version:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new
            {
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x40 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, Value = (uint)0x20 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, Value = (uint)0x80 },
            new { Flags = new { DataSectionFlags.MemoryExecute, }, Value = (uint)0x10 },
            new { Flags = new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x04 },
            new { Flags = new { DataSectionFlags.MemoryRead, }, Value = (uint)0x02 },
            new { Flags = new { DataSectionFlags.MemoryWrite, }, Value = (uint)0x08 },
            new { Flags = new DataSectionFlags { }, Value = (uint)0x01 },
            };

            result |= ladder.Where(x => x.Flags.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }





            share|improve this answer















            This is the best that I could come up with at short notice:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new KeyValuePair<DataSectionFlags, uint>
            {
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x40),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, 0x20),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, 0x80),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryExecute, }, 0x10),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, 0x04),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryRead, }, 0x02),
            new KeyValuePair<DataSectionFlags, uint>(new { DataSectionFlags.MemoryWrite, }, 0x08),
            new KeyValuePair<DataSectionFlags, uint>(new DataSectionFlags { }, 0x01),
            };

            result |= ladder.Where(x => x.Key.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }




            A possibly more readable version:



            private static uint GetSectionProtection(DataSectionFlags characteristics)
            {
            uint result = 0;

            if (characteristics.HasFlag(DataSectionFlags.MemoryNotCached))
            {
            // PageNoCache
            result |= 0x200;
            }

            var ladder = new
            {
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x40 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryRead, }, Value = (uint)0x20 },
            new { Flags = new { DataSectionFlags.MemoryExecute, DataSectionFlags.MemoryWrite, }, Value = (uint)0x80 },
            new { Flags = new { DataSectionFlags.MemoryExecute, }, Value = (uint)0x10 },
            new { Flags = new { DataSectionFlags.MemoryRead, DataSectionFlags.MemoryWrite, }, Value = (uint)0x04 },
            new { Flags = new { DataSectionFlags.MemoryRead, }, Value = (uint)0x02 },
            new { Flags = new { DataSectionFlags.MemoryWrite, }, Value = (uint)0x08 },
            new { Flags = new DataSectionFlags { }, Value = (uint)0x01 },
            };

            result |= ladder.Where(x => x.Flags.All(y => characteristics.HasFlag(y))).First().Value;

            return result;
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 21 '18 at 3:55

























            answered Nov 21 '18 at 1:54









            EnigmativityEnigmativity

            77.7k966135




            77.7k966135








            • 4





              Clever, but I find the original significantly more clear and readable (and thus maintainable)...

              – TypeIA
              Nov 21 '18 at 2:02






            • 1





              @TypeIA - Yes, I agree. What makes this interesting is that this is configurable. The ladder can be changed at run-time or read from a config file. But I do agree that it's not as easy to follow.

              – Enigmativity
              Nov 21 '18 at 2:38






            • 1





              This is more maintainable. The KVP instantiations is a data structure that clearly associates flags; no triple nested if's needed! Comparatively, data structure always results in simpler code: 9 "result =" blocks collapse to 1 line! Modifying that if-else/if nest requires more mental energy and is necessarily more error prone than non-branching code. A 1-line comment will explain what uint (the value in the KV pair) is; this is an understandability issue, not readability. This answer is pleasantly readable vis-a-vis a nested control structure.

              – radarbob
              Nov 21 '18 at 3:40
















            • 4





              Clever, but I find the original significantly more clear and readable (and thus maintainable)...

              – TypeIA
              Nov 21 '18 at 2:02






            • 1





              @TypeIA - Yes, I agree. What makes this interesting is that this is configurable. The ladder can be changed at run-time or read from a config file. But I do agree that it's not as easy to follow.

              – Enigmativity
              Nov 21 '18 at 2:38






            • 1





              This is more maintainable. The KVP instantiations is a data structure that clearly associates flags; no triple nested if's needed! Comparatively, data structure always results in simpler code: 9 "result =" blocks collapse to 1 line! Modifying that if-else/if nest requires more mental energy and is necessarily more error prone than non-branching code. A 1-line comment will explain what uint (the value in the KV pair) is; this is an understandability issue, not readability. This answer is pleasantly readable vis-a-vis a nested control structure.

              – radarbob
              Nov 21 '18 at 3:40










            4




            4





            Clever, but I find the original significantly more clear and readable (and thus maintainable)...

            – TypeIA
            Nov 21 '18 at 2:02





            Clever, but I find the original significantly more clear and readable (and thus maintainable)...

            – TypeIA
            Nov 21 '18 at 2:02




            1




            1





            @TypeIA - Yes, I agree. What makes this interesting is that this is configurable. The ladder can be changed at run-time or read from a config file. But I do agree that it's not as easy to follow.

            – Enigmativity
            Nov 21 '18 at 2:38





            @TypeIA - Yes, I agree. What makes this interesting is that this is configurable. The ladder can be changed at run-time or read from a config file. But I do agree that it's not as easy to follow.

            – Enigmativity
            Nov 21 '18 at 2:38




            1




            1





            This is more maintainable. The KVP instantiations is a data structure that clearly associates flags; no triple nested if's needed! Comparatively, data structure always results in simpler code: 9 "result =" blocks collapse to 1 line! Modifying that if-else/if nest requires more mental energy and is necessarily more error prone than non-branching code. A 1-line comment will explain what uint (the value in the KV pair) is; this is an understandability issue, not readability. This answer is pleasantly readable vis-a-vis a nested control structure.

            – radarbob
            Nov 21 '18 at 3:40







            This is more maintainable. The KVP instantiations is a data structure that clearly associates flags; no triple nested if's needed! Comparatively, data structure always results in simpler code: 9 "result =" blocks collapse to 1 line! Modifying that if-else/if nest requires more mental energy and is necessarily more error prone than non-branching code. A 1-line comment will explain what uint (the value in the KV pair) is; this is an understandability issue, not readability. This answer is pleasantly readable vis-a-vis a nested control structure.

            – radarbob
            Nov 21 '18 at 3:40




















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404118%2fhow-could-i-simplify-this-long-chain-of-conditional-statements%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            鏡平學校

            ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

            Why https connections are so slow when debugging (stepping over) in Java?