C# - 引用 "this int" 参数

C# - Referencing "this int" parameter



我有非常简单的按位运算符方法,我想这样使用:

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' 的内部值,而不是原始变量,因为整数不是引用类型。
我不能将 'ref' 与 'this' 一起使用,所以我不知道如何将其转换为参考参数。
我已经为 Int 数组提供了类似的方法,但这些方法工作正常,因为数组是引用类型。

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

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

使您的方法 return 修改后的值并将其分配回您的变量。该方法将与不可变类型保持一致。考虑 String.Replace 的示例,它不会就地修改字符串,而是 return 修改后的副本。

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

    return A;
}

我不得不检查一下,因为它看起来有点奇怪。果然 - 您不能使用 ref.

编写扩展方法

See here,其他人已经试过了。

我建议只返回结果而不是试图改变不可变的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);

有些类型(如 ints)是不可变的,这意味着一旦它们被设置为一个值,就不能再更改。您会注意到任何处理 int 的方法都会 return 一个新的 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);

您不能在扩展方法中混合使用 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 class 而不是 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);