开发者

Can I pass primitive types by reference in C#?

开发者 https://www.devze.com 2023-03-29 12:54 出处:网络
I know complex types are passed by Reference in C# and primitive types are passed by Value. C开发者_开发百科an I pass primitive types by reference in C#?

I know complex types are passed by Reference in C# and primitive types are passed by Value. C开发者_开发百科an I pass primitive types by reference in C#?

Update:

Thanks for answers, but my example is?

void test(object x) {

}

long y = 1;

test(ref y);

This throw this exception: The 'ref' argument type doesn´t match parameter type


There are a couple of different questions here.

Can I pass primitive types by reference in C#?

First off, let's make sure that the jargon is correct here. It is unclear what you mean by a "primitive type". Do you mean a "built into the runtime" type like int or long? Do you mean any value type whether it is built-in or user-defined?

I'm going to assume that your question actually is

Can I pass value types by reference in C#?

Value types are called value types because they are passed by value. Reference types are called reference types because they are passed by reference. So it would seem that the answer is by definition, no.

However, it's not quite so straightforward as that.

First, you can turn an instance of value type into an instance of reference type by boxing it:

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

Second, you can turn an instance of value type into a reference by making an array:

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

Third, you can pass a reference to a variable (not a value -- a variable) using the "ref" keyword:

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

Attempting to pass a ref long to a method that takes a ref object causes a compilation error: The 'ref' argument type doesn´t match parameter type

Correct. The type of the variables on both sides must match exactly. See this question for details:

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


Sure you can:

public void MyFunction(ref int a)
{
}


Just use the ref or out parameter modifier.

void myMethod(ref int myValue) ...

ref is 2 way. out is 1 way.


You can using the ref word next to the parameter in the function definition.

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

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


You're mixing concepts. The default parameter passing convention is by value. You can pass a reference type object to a method or pass a value type object to the method. You pass the object by using a variable. That variable is passed by value. Inside the method, the parameter is a copy of the variable you passed.

If you decorate the parameter with ref or out, then mutating what you have inside the method will also affect the passed variable.

// 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);

To mutate a primitive type variable parameter inside a method and persist the change at the call site, it must be passed by ref or out.


Post-update you can pass boxed values around by reference.

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

Just keep in mind it's terrible practice, and risky (due to cast exceptions) to do this.

0

精彩评论

暂无评论...
验证码 换一张
取 消