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

时间:2011-08-19 13:17:05

标签: c# .net

我知道C#中的Reference传递复杂类型,而Value传递基本类型。我可以在C#中通过引用传递原始类型吗?

更新

感谢您的回答,但我的例子是?

void test(object x) {

}

long y = 1;

test(ref y);

抛出此异常:'ref'参数类型与参数类型

不匹配

6 个答案:

答案 0 :(得分:19)

这里有几个不同的问题。

  

我可以在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'参数类型与参数类型不匹配

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

Why doesn't 'ref' and 'out' support polymorphism?

答案 1 :(得分:15)

当然可以:

public void MyFunction(ref int a)
{
}

答案 2 :(得分:8)

只需使用refout参数修饰符。

void myMethod(ref int myValue) ...

ref是双向的。 out是单向的。

答案 3 :(得分:7)

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

public void func(ref int a)
{
    //do stuff
}

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

答案 4 :(得分:2)

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

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;
}

请记住这是一种可怕的做法,并且冒着风险(由于演员例外)这样做。

答案 5 :(得分:1)

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

如果使用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传递。