C#-引用";该int";参数

本文关键字:quot 参数 int 引用 C#- | 更新日期: 2023-09-27 18:02:32



我有非常简单的Bitwise Operator方法,我想这样使用:

myInt.SetBit(int k, bool set)

因此,它将索引"k"处的位更改为值"set"(0或1(。我第一次想到这样做:

public static void SetBit(this int A, int k, bool set) { 
    if (set) A |= 1 << k; 
    else A &= ~(1 << k); 
}

当然,这只会更改变量"A"的内部值,而不会更改原始变量,因为integer不是引用类型
我不能将"ref"与"this"一起使用,所以我不知道如何将其转换为引用参数
我已经为Int数组提供了类似的方法,但由于数组是引用类型,所以这些方法可以很好地工作。

我正在寻找一种方法来为单个整数保留这种方便的语法,如果有的话。

C#-引用";该int";参数

您不应该将其视为引用类型。

使方法返回修改后的值,并将其重新分配给变量。这种方法将与不可变类型保持一致。以String.Replace为例,它不会在适当的位置修改字符串,而是返回一个修改后的副本。

public static int SetBit(this int A, int k, bool set)
{
    if (set) A |= 1 << k;
    else A &= ~(1 << k);
    return A;
}

有些类型(如ints(是不可变的,这意味着一旦将它们设置为值,就不能再更改它们。您会注意到,任何处理int的方法都将返回一个新的int,而不是更改给定值的值。

更新你的代码如下:

public static int SetBit(this int A, int k, bool set) { 
    if (set) A |= 1 << k; 
    else A &= ~(1 << k); 
    return A;
}

并像一样使用

var x = 5;
x = x.SetBit(1, true);

我建议返回结果,而不是尝试更改不可变的int:

  // int instead of void
  public static int SetBit(this int A, int k, bool set) { 
    return set ? (A | (1 << k)) : (A & (~(1 << k))); 
  }

所以你可以做

  int source = 12345;
  int result = source.SetBit(3, true);

我不得不检查一下,因为它看起来有点奇怪。果不其然,您无法使用ref编写扩展方法。

看到这里,其他人已经尝试过了。

不能在扩展方法中混合使用thisref。你有很多选择:

  1. 从扩展方法返回结果(我更喜欢这个选项(:

    public static int SetBit(this int A, int k, bool set)
    {
        if (set) A |= 1 << k;
        else A &= ~(1 << k);
        return A;
    }
    

    使用:

    int i = 3;       
    i = i.SetBit(1, false); 
    
  2. 使用ref:的方法

    public static void SetBitRef(ref int A, int k, bool set)
    {
        if (set) A |= 1 << k;
        else A &= ~(1 << k);
    }
    

    使用:

        int i = 3;
        IntExtensions.SetBitRef(ref i, 1, false);
    
  3. 使用IntWrapper类而不是int:

        class IntWrapper
        {
            public IntWrapper(int intValue)
            {
                Value = intValue;
            }
            public int Value { get; set; }
        }
    

    使用引用类型,可以创建以下扩展方法:

    public static void SetBit(this IntWrapper A, int k, bool set)
    {
        int intValue = A.Value;
        if (set) intValue |= 1 << k;
        else intValue &= ~(1 << k);
        A.Value = intValue;
    }
    

    使用:

    IntWrapper iw = new IntWrapper(3);
    iw.SetBit(1, false);