我知道在C#中,复杂类型是按引用传递的,而原始类型是按值传递的。那我能否在C#中通过引用传递原始类型呢?
更新:感谢回答,但我的问题是什么?
更新:感谢回答,但我的问题是什么?
void test(object x) {
}
long y = 1;
test(ref y);
出现以下异常:“ref”参数类型与参数类型不匹配
这里有几个不同的问题。
我能在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 object 的方法会导致编译错误: 'ref' 参数类型与参数类型不匹配
是的,两边变量的类型必须完全一致。有关详细信息,请参见此问题:
当然可以:
public void MyFunction(ref int a)
{
}
只需使用ref
或out
参数修饰符即可。
void myMethod(ref int myValue) ...
ref
是双向的。
out
是单向的。
ref
关键字。public void func(ref int a)
{
//do stuff
}
public void doStuf()
{
int a = 5;
func(ref a);
}
ref
传递。 - Danielref
或 out
修饰参数,则在方法内部更改该参数也将影响传递的变量。// 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);
如果要在方法内部改变一个基本类型变量的参数并在调用点保持更改,必须通过ref
或out
传递。
更新后,您可以通过引用传递封装的值。
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;
}
请记住,这种做法很糟糕,并且存在风险(由于类型转换异常)。
void test (ref object x)
,因为ref
需要在方法定义和使用中都被使用。 - Alexref
。 - Daniel