C#扩展方法返回值未设置变量

时间:2014-08-13 14:38:36

标签: c# extension-methods

为什么此扩展方法没有设置应用的值?

public static byte ExtSetBits(this byte original, byte value, byte bitSize)
{
    unchecked { original &= (byte)~bitSize; }
    original |= (byte)(value & bitSize);
    return original;
}

这是一个电话(selectedIndex = 13):

byte test = 0xFF;
test.ExtSetBits(selectedIndex, 0x1F);
Console.WriteLine("test:" + test.ToString("X").PadLeft(2,'0'));

写作"测试:FF"到控制台。

如果我这样做有效:

byte test = 0xFF;
test = test.ExtSetBits(selectedIndex, 0x1F);
Console.WriteLine("test:" + test.ToString("X").PadLeft(2,'0'));

写作"测试:ED"到控制台。我不应该重新分配变量吗?我已经写了很多其他扩展。

3 个答案:

答案 0 :(得分:6)

  

我错过了什么吗?

是的 - 您不是在第一个代码段中使用方法的返回值。您所需要的只是设置返回值,就像您在工作案例中所做的那样(您的第二个代码段)。更改参数的值没有区别,因为它是一个按值参数。你在这里使用扩展方法这一事实无关紧要。

想象一下,您的代码实际上只是

ExtensionClass.ExtSetBits(test, selectedIndex, 0x1F);

毕竟,这就是编译器将代码转换为的内容。如果你忽略了它是一种扩展方法(你应该,因为它在这里无关紧要),你会期望改变test的值吗?要做到这一点,您需要通过引用传递它(使用ref) - 但扩展方法的第一个参数不允许具有ref修饰符。

您可能需要阅读my article about parameter passing以获取更多背景信息以及my article about value types and reference types

答案 1 :(得分:2)

byte是一种值类型。 testoriginal都是不同的值,修改一个不会修改另一个。

答案 2 :(得分:1)

您没有在函数中修改测试的值。参数是变量的副本,您正在更改它的值然后返回它。如果您想操纵变量,那么您应该使用ref修饰符,但扩展方法的第一个参数不能声明为ref