这是解析函数参数的有效方法吗?

时间:2018-04-27 16:14:47

标签: c# bit-manipulation multiplexing

所以我是C#的新手,但我已经想从其他更高级语言中获得的一件事就是能够在(接近)C中进行按位操作。我有一些函数,其中一些或所有参数都是可选的,我喜欢开关,所以我构建了一个将布尔数组转换为无符号短脚的函数,它允许我基本上将布尔数组Mux为交换机的单个值:

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;               
        }
    }
}

以下是一个用例示例:

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();
    }

我的问题是,这是一种有效的方法,还是有一种优越的方式?我的目标是简单的使用,这绝对为我提供,但我也希望它是在运行时快速的高效代码。有什么指针吗?这是一种愚蠢的方式吗?欢迎提出任何反馈意见,如果你相信,你甚至可以称我为白痴,我不太敏感。谢谢!

1 个答案:

答案 0 :(得分:9)

这一切都很糟糕。

编写方法的正确方法是不使用以下方法:

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

我已经喜欢从其他更高级别的语言中获得的一件事是能够在(接近)C中进行按位操作。

如果您正在努力解决高级别的业务问题,那么您可能做错了什么。使用高级业务代码解决高级业务问题。

另外,如果你在C#中使用无符号类型,那么你可能做错了。无符号类型用于与非托管代码进行互操作。在C#中使用ushort或uint或ulong是非常罕见的。逻辑上无符号的数量(如数组的长度)始终表示为有符号数量。

C#有许多功能,旨在确保拥有COM库的人可以继续使用他们的库,以便需要原始的,未经检查的指针运算性能的人在合理安全时可以这样做。不要将这些低级编程功能的存在误认为是C#通常用作低级编程语言的证据。编写代码,使其清楚地读取作为业务工作流的实现

您的代码的业务是将名称呈现为字符串,因此它应该清楚地读作将名称呈现为字符串。如果我要求你在一张纸上写下一个名字,那么你要做的第一件事就是不要做一点帮助你,所以它也不应该在这里。

现在,可能在某些情况下这类事情是明智的,在这种情况下你应该使用枚举而不是将短路视为一个字段

[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;
}

现在你有一个方便的

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

但请注意我们将所有内容保留在业务领域。我们在做什么? 检查权限。那么代码是什么样的? 就像检查权限一样。没有弄乱一堆比特然后接通一个整数。