C# 值类型扩展方法是否提供对原始值的写访问?

C# 值类型扩展方法是否提供对原始值的写访问?,c#,.net,pass-by-reference,extension-methods,value-type,C#,.net,Pass By Reference,Extension Methods,Value Type,我正在为一些定制的小容量编码和解码算法编写值类型(如int)的扩展方法。 可能还有其他设计不使用扩展方法,但我担心这不是我最后一次面对这个问题,所以我想知道扩展方法如何与这种类型的设计一起工作 例如: int i = 10; string str = i.Encode(); // Convert 10 to an unpredictable string such as "tZh0Ao" i = 5; // Overwrite i with a new value. i.Decode(st

我正在为一些定制的小容量编码和解码算法编写值类型(如
int
)的扩展方法。
可能还有其他设计不使用扩展方法,但我担心这不是我最后一次面对这个问题,所以我想知道扩展方法如何与这种类型的设计一起工作

例如:

int i = 10;

string str = i.Encode(); // Convert 10 to an unpredictable string such as "tZh0Ao"

i = 5; // Overwrite i with a new value.

i.Decode(str); // Decrypt the string to reassign the original value of 10
/* This method will decode a string,
   and assign the decoded value to 'this' int. */

public static void Decode(this int value, string str)
{
    int result;

    /* ... perform work with str to produce decoded value ... */

    value = result; // Assign the decoded value to 'this' int.

    /* If 'value' is just a copy of the original int,
       the assignment won't have any permanent effect. */
}
我不确定
这个
参数如何用于值类型扩展方法。
它只是原值的副本吗?
或者它是否像
ref
out
参数一样工作,保留对参数值所做的更改

例如:

int i = 10;

string str = i.Encode(); // Convert 10 to an unpredictable string such as "tZh0Ao"

i = 5; // Overwrite i with a new value.

i.Decode(str); // Decrypt the string to reassign the original value of 10
/* This method will decode a string,
   and assign the decoded value to 'this' int. */

public static void Decode(this int value, string str)
{
    int result;

    /* ... perform work with str to produce decoded value ... */

    value = result; // Assign the decoded value to 'this' int.

    /* If 'value' is just a copy of the original int,
       the assignment won't have any permanent effect. */
}
我想知道扩展方法如何与这种类型的设计配合使用

他们不是

C#3.0中引入了扩展方法,以允许LINQ查找
。为任何
IEnumerable
IQueryable
实例选择
和其他方法,而无需这些接口的每个实现都重新定义方法,并且不破坏已经实现了
IEnumerable
的大量现有代码

允许此操作不需要允许
此ref
扩展方法。这并不意味着这些扩展方法没有意义,或者它们没有用处,只是在创建扩展方法时没有考虑它们

这和我们没有扩展属性的原因是一样的。允许扩展属性被认为是WPF附加属性IIRC的一部分,但尽管它们可能有意义,但最终证明它们对于预期目标是不必要的,因此被排除在C语言之外

如果
这个ref
扩展方法有令人信服的理由,请向语言设计者提出。这就是添加任何新语言功能的方式。如果还没有令人信服的原因,那么修改编译器所需的额外工作通常是不修改语言的原因

它只是原值的副本吗

对。编译器将所有扩展方法调用转换为等效的静态方法调用<代码>i.ExtensionMethod()
ExtensionClass.ExtensionMethod(i)做同样的事情。如果后者不能修改
i
(因为它没有声明为
ref
),则前者也不能

在.NET Framework中,您也不会发现许多变化的实例方法。通常认为最好让实例方法返回一个新值,并让调用方担心是将其分配给现有实例还是新实例。假设
DateTime.AddDays
修改了调用它的实例(可以这样设计类型)。那么典型的程序员就不会明白为什么了

public void AddOneDay(DateTime[] array) {
  for (int i = 0; i < array.Length; i++)
    array[i].AddDays(1);
}
扩展方法,并将其用作

i = str.Decode();

完全避免这个问题。

它没有经过
ref
,因此它不会更新您调用它的原始变量。您可能想检查它,让它返回
int
会更好<代码>公共静态整数解码(字符串str)
。因此,代替
i.Decode(str)它将是
i=Decode(str)