我可以在C#中通过引用传递基元类型吗

本文关键字:类型 引用 我可以 | 更新日期: 2023-09-27 18:06:20

我知道复杂类型是由C#中的Reference传递的,基元类型是由Value传递的。我可以在C#中通过引用传递基元类型吗?

更新:

谢谢你的回答,但我的例子是?

void test(object x) {
}
long y = 1;
test(ref y);

这引发了以下异常:"ref"参数类型与参数类型不匹配

我可以在C#中通过引用传递基元类型吗

这里有几个不同的问题。

我可以在C#中通过引用传递基元类型吗?

首先,让我们确保这里的行话是正确的。你所说的"原始类型"是什么意思还不清楚。你的意思是像int或long这样的"内置运行时"类型吗?你指的是任何值类型,无论是内置的还是用户定义的?

我假设你的问题实际上是

我可以在C#中通过引用传递值类型吗?

值类型被称为值类型,因为它们是通过值传递的。引用类型被称为引用类型,因为它们是通过引用传递的。因此,根据定义,答案似乎是否定的。

然而,事情并没有那么简单。

首先,您可以将值类型的实例装箱为引用类型的实例:

decimal d = 123.4m; // 128 bit immutable decimal structure
object o1 = d; // 32/64 bit reference to 128 bit decimal
object o2 = o1; // refers to the same decimal
M(o2); // passes a reference to the decimal.
o2 = 456.78m; // does NOT change d or o1

其次,您可以通过创建数组将值类型的实例转换为引用:

decimal[] ds1 = new decimal[1] { 123.4m }; 
decimal[] ds2 = ds1;
ds2[0] = 456.7m; // does change ds1[0]; ds1 and ds2 refer to the same array

第三,您可以使用"ref"关键字传递对变量(而不是值——变量(的引用:

decimal d = 123.4m;
M(ref d);
...
void M(ref decimal x)
{ // x and d refer to the same variable now; a change to one changes the other

试图将ref long传递给接受ref对象的方法会导致编译错误:"ref"参数类型与参数类型不匹配

正确。两边的变量类型必须与完全匹配。有关详细信息,请参阅此问题:

为什么不';t';ref';和';out';支持多态性?

当然可以:

public void MyFunction(ref int a)
{
}

只需使用refout参数修饰符。

void myMethod(ref int myValue) ...

CCD_ 3是双向的。out是单向的。

您可以在函数定义中的参数旁边使用ref字。

public void func(ref int a)
{
    //do stuff
}
public void doStuf()
{
    int a = 5;
    func(ref a);
}

您正在混合概念。默认的参数传递约定为按值。可以将引用类型对象传递给方法,也可以将值类型对象传递到方法。通过使用变量传递对象。该变量通过值传递。在方法内部,参数是您传递的变量的副本

如果用refout修饰参数,那么更改方法内部的也会影响传递的变量。

// Doesn't change obj1
void DoesntChange(object obj)
{
    obj = new object(); // Assigns a new object to the local variable obj.
}
var obj1 = new object();
DoesntChange(obj1);
// Will change obj2
void WillChange(ref object obj)
{
    obj = new object(); // Assigns a new object to the local ref variable obj
                        // and changes the obj2 variable to point at the new object.
}
var obj2 = new object();
WillChange(ref obj2);

若要在方法内更改基元类型变量参数并将更改保留在调用站点,必须由refout传递。

更新后,您可以通过引用传递装箱值

static void Main(string[] args)
{
    var value = 10;
    var boxed = (object)value;
    TakesValueByRef(ref boxed);
    value = (int)boxed;
    // value now contains 5.
}
static void TakesValueByRef(ref object value)
{
    value = 5;
}

请记住,这是一种可怕的做法,而且有风险(由于演员阵容的例外(。