Is this an efficient way to parse function parameters?

  • A+
Category:Languages

So I am new to C#, but one thing I already like coming from other higher level languages is the ability to do bitwise operations in (close to) C. I have a bunch of functions where some or all parameters are optional, and I like switches, so I built a function that converts boolean arrays to unsigned Shorts which allows me to basically Mux a boolean array to a single value for the switch:

namespace firstAsp.Helpers{     public class argMux{                                public static ushort ba2ushort (bool[] parms){               //initialize position and output                             ushort result = 0;             int i = parms.Length-1;             foreach (bool b in parms){                 if (b)//put a one in byte at position of b                     //bitwise or with position                     result |= (ushort)(1<<i);                 i--;             }             return result;                        }     } } 

Here is an example use case:

public IActionResult Cheese(string fname,string lname)     {         bool[] tf = {fname!=null,lname!=null};          switch(argMux.ba2ushort(tf)){          case 3:             @ViewData["Data"]=$"Hello, {fname} {lname}";             break;          case 2:             @ViewData["Data"]=$"Hello, {fname}";             break;          case 1:             @ViewData["Data"]=$"Hello, Dr. {lname}";             break;          case 0:             @ViewData["Data"]="Hello, Dr. CheeseBurger";             break;         }         return View();     } 

My question is, Is this an efficient way to do this, or is there a way that is superior? I am aiming for simplicity of use which this definitely delivers for me, but I would also like it to be efficient code that is fast at runtime. Any pointers? Is this a stupid way to do this? Any and all feedback is welcome, you can even call me an idiot if you believe it, I'm not too sensitive. Thanks!


This is all bad.

The correct way to write your method is to use none of this:

public IActionResult Cheese(string firstName, string lastName) {     @ViewData["Data"]=$"Hello, {firstName ?? "Dr."} {lastName ?? "Cheeseburger"}";     return View(); } 

one thing I already like coming from other higher level languages is the ability to do bitwise operations in (close to) C.

If you are twiddling bits to solve a high level business problem, you are probably doing something wrong. Solve high-level business problems with high-level business code.

Also, if you are using unsigned types in C#, odds are good you are doing something wrong. Unsigned types are there for interoperability with unmanaged code. It is very rare to use a ushort or a uint or a ulong for anything else in C#. Quantities which are logically unsigned, like the length of an array, are always represented as signed quantities.

C# has many features which are designed to ensure that people who have COM libraries can continue to use their libraries, and so that people who need the raw, unchecked performance of pointer arithmetic can do so when it is reasonably safe. Don't mistake the existence of those low-level programming features as evidence that C# is typically used as a low-level programming language. Write your code so that it reads clearly as an implementation of a business workflow.

The business of your code is rendering a name as a string, so it should clearly read as rendering a name as a string. If I asked you to write down a name on a piece of paper, the first thing you'd do would not be to make a bit array to help you, so it shouldn't be here either.

Now, there might be some cases where this sort of thing is sensible, and in those cases you should use an enum rather than treating a short as a bit field:

[Flags] enum Permissions  {   None = 0x00,   Read = 0x01,   Write = 0x02,   ReadWrite = 0x03,   Delete = 0x04,   ReadDelete = 0x05,   WriteDelete = 0x06,   ReadWriteDelete = 0x07 } ... static Permissions GetPermission(bool read, bool write, bool delete) {   var p1 = read ? Permissions.Read : Permissions.None;   var p2 = write ? Permissions.Write : Permissions.None;   var p3 = delete ? Permissions.Delete : Permissions.None;   return p1 | p2 | p3; } 

And now you have a convenient

switch(p) {   case Permissions.None: ...   case Permissions.Read: ...   case Permissions.Write: ...   case Permissions.ReadWrite: ... 

But notice here that we keep everything in the business domain. What are we doing? Checking permissions. So what does the code look like? Like it is checking permissions. Not twiddling a bunch of bits and then switching on an integer.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: