How to pass references as arguments in a method in c# - c#

How can you pass refernces in C#?

private void functionName (ref Type variableName)
{
}
To Call it
functionName(ref variable);

Your question is extremely unclear, but it's quite possible that my article on parameter passing in C# will answer whatever you really intended to ask.
In particular, you need to distinguish between passing a reference by value, and passing an argument by reference. If you're hazy on value types and reference types, you might also want to look at my article on that topic.

You can pass parameters by reference in C# using this syntax.
public void MyMethod(ref string myString)
{
}
You will then need to put ref before the value when passing it.

Jon Skeet has a good article on this here.
In C#, value types (like int, double, byte and structs) are passed by value, by default. This means that the receiving method has a NEW instance of the type. If an int that has a value of 1 is passed to the method, and the method changes it to 2, this change is only reflected within the method, the calling location's int is still 1. If however the ref keyword is added, then changes made to that integer are reflected back to the calling location.
All classes in C# are reference types. This means, by default, the references are passed by value. This is the important part. This means, changes made to that instance of the object are reflected back to the calling location, because it is the same object. However, if the method changes it's reference to a different object, this change is not reflected. In the case you want these changes reflected back, you would need to use the ref keyword on the parameter.
public static void Main()
{
int i = 1;
Method1(i); //i here is still 1
Method2(ref i); //i is now 2
SimpleObj obj = new SimpleObj();
obj.Value = 1;
Method3(obj); //obj.Value now 2
Method4(obj); // obj.Value still 2
Method5(ref obj); //obj.Value now 5
}
private static void Method5(ref SimpleObj obj)
{
obj = new SimpleObj();
obj.Value = 5;
}
private static void Method4(SimpleObj obj)
{
obj = new SimpleObj();
obj.Value = 5;
}
private static void Method3(SimpleObj obj)
{
obj.Value++;
}
private static void Method2(ref int i)
{
i++;
}
private static void Method1(int i)
{
i++;
}
public class SimpleObj
{
public int Value { get; set; }
}
The ref keyword is covered in section 10.6.1.2 of the C# 3.0 specification. Here is the msdn documentation.

Here is a nice overview of parameter passing in C#:
http://www.yoda.arachsys.com/csharp/parameters.html

Calling Code:
string companyName = "New Company";
GetEmail(ref companyName);
Method Code:
private void GetEmail(ref string companyName)
{
}

Your questions isn't clear, but I'd like to point out that in C#, objects are passed by reference by default. Meaning, if you have an object, and then pass that object on to a method that makes changes to that object, those changes will affect the object in your calling code as well, since they both reference the same object.

Related

Pointers are unsafe but I don't understand ref

I want a singleton Problem with a "square" 2x2.
I want to be able to refer to the case by row.
I want to be able to refer to the row by case.
I know I could easily do this in C++ with pointers but it seems like a bad habit to do.
I don't understand how to link my "row" and my "case" together.
The same logic will be there for column but isn't describe in the code
The goal is so changing the value of a Case would affect the value reffered in the Row. How can I achieve this without pointer and with Ref?
class Program
{
static void Main(string[] args)
{
Problem.Instance().Show();
Problem.Instance().Change();
Problem.Instance().Show();
}
public class Problem
{
private Case[] cases = null;
private Row[] rows = null;
// same logic with private Column[] columns = null;
static Problem instance = null;
private Problem()
{
cases = new Case[4];
rows = new Row[2];
int i = 0;
for (i = 0; i < 4; i++)
cases[i] = new Case();
for (i = 0; i < 2; i++)
rows[i] = new Row(i);
}
public static Problem Instance()
{
if (instance == null)
instance = new Problem();
return instance;
}
public Case LinkToRow(int i, ref Row r)
{
cases[i].LinkToRow(r);
return cases[i];
}
public void Show()
{
rows[0].Show();
}
public void Change()
{
cases[0].Change();
cases[1].Change();
}
}
public class Row
{
private Case[] ref cases = null;
public Row(int i)
{
ref Row r = this;
cases = new Case[2];
cases[0] = Problem.Instance().LinkToRow(0, ref r);
cases[1] = Problem.Instance().LinkToRow(1, ref r);
}
public void Show()
{
Console.WriteLine("{0},{1}", cases[0].Val, cases[1].Val);
}
}
public class Case
{
private int val;
private ref Row r = null;
public Case()
{
}
public void LinkToRow(Row rr)
{
r = rr;
}
public int Val { get { return val; } }
public void Change()
{
val++;
}
}
}
In C#, private Row r = null; declares a rebindable reference to an instance of Row. ref is illegal there and not needed.
In C++, private: Row r; would be an instance of Row, not a reference. C++ is a different language with very different rules. C# classes can't "be on the stack"; they're always dynamically allocated, and the only way you can manipulate one is via a reference.
In C#, your private Row r; is already a reference. A C# reference is kind of like a pointer that you don't have to (and can't) explicitly dereference. Because it's always dereferenced, you can't do pointer arithmetic either. They're subject to many of the same polite fictions ("let's make them pretend it's not a pointer") as C++ references. Just take out ref.
A C# struct (e.g. System.DateTime) is more like a stack instance of a C++ class. This is very different from the C++ struct/class distinction.
The C# ref keyword is a different animal. Nothing to do with references.
In C#, the example below illustrates what the ref keyword is for: Passing references by reference instead of by value. That sounds like I'm pulling your leg but I'm not.
To explain it in terms of C++ semantics, passing a C# reference "by value" is like passing a pointer. You can change the object the caller's pointer points at, but you can't change the caller's pointer itself. You have only the value of the caller's pointer.
Passing a C# reference by reference is like passing in a pointer to a pointer: You can set (*p)->Foo = 3;, and you can also set *p = new Bar(); (I'm rusty on C/C++, corrections welcomed).
public static void F()
{
String x = "original value";
FByValue(x);
Console.WriteLine(x);
FByReference(ref x);
Console.WriteLine(x);
}
public static void FByValue(String s)
{
s = "different value for local copy of parameter only";
}
public static void FByReference(ref String s)
{
s = "different value for caller's copy, thanks to ref keyword";
}
ref works only with parameters, never ever with fields; see MSDN for more detail.
Lastly: FByValue() and FByReference() would have identical semantics with int instead of String.
In C# there is a difference between value types and references.
First, there is nothing wrong with pointers in C/C++, that's how the language works and, that's how the hardware works as well. They can just be confusing to the new user.
In C#, the definition of structures and classes is different than C++:
if you define your data structures as struct or as class.
A struct is an object that gets copied around as it is passed from calls to calls. A class on the other hand gets its pointer passed around, similar to a C++ pointer, so if you have references to class instances in C#, you're really referencing the same object, and changes done at one place will be reflected everywhere you hold a reference to that object.

EF Add method Identity Column value

I may sound stupid question to you, but I really want to know it.
in Entity Framework (EF) on context class DbSet when we call Add(object) method , how it update the Id column on entity. I mean if its using "REF" and "OUT" we can understand how it update the ID field but here without using REF and OUT how it can under the object property.??
//model.ID -- here its zero
context.Entry(model).State = EntityState.Added;
context.SaveChanges();
//model.ID -- here its no zero
This is explained much more thoroughly in the C# documentation types, but here the gist of it:
Value types are items like int, bool, any struct, etc. These are blocks of memory that hold a distinct value.
Reference types are items like string, object, any class, etc. These are actually just 'references' to the block of memory holding their value.
If you pass a value type as a parameter to a method, then that value is essentially copied into a new block of memory and the original value cannot be modified by the code in the method.
public static void Main()
{
int myInt = 5;
Console.WriteLine(myInt);
ChangeMe(myInt);
Console.WriteLine(myInt);
}
public static void ChangeMe(int i)
{
i = 7;
}
// Outputs:
// 5
// 5
In order to modify a value type, you have to use the "ref" or an "out" parameter.
public static void Main()
{
int myInt = 5;
Console.WriteLine(myInt);
ChangeMe(ref myInt);
Console.WriteLine(myInt);
}
public static void ChangeMe(ref int i)
{
i = 7;
}
// Outputs:
// 5
// 7
This, however, does not apply to types that are already reference types. Typically, in entity framework you work with types that are set up as class objects. These are reference types by default. Passing a reference type to a method does not 'copy' it like a value type does, the method instead gets access to the original object. This is because you are merely passing a location to where that memory lives. This manifests in allowing the method to modify the values on the class.
public class MyClass
{
public int MyInt { get; set; }
}
public static void Main()
{
MyClass myclass = new MyClass();
myclass.MyInt = 5;
Console.WriteLine(myclass.MyInt);
ChangeMe(myClass);
Console.WriteLine(myclass.MyInt);
}
public static void ChangeMe(MyClass i)
{
i.MyInt = 7;
}
// Outputs:
// 5
// 7

passing objects as parameters

The application is printing 24 but shouldn't it be printing 18 when we know that without ref keyword only a copy of object is passed and no change is made to the original object.
I have created a class called myclass and an object me. age is a public variable in class myclass.
I have set me.age as 18 and through the method show I have changed it to 24.
class Program
{
static void Main(string[] args)
{
myclass me = new myclass();
me.age = 18;
show(me);
Console.WriteLine(me.age);
Console.ReadLine();
}
public static void show( myclass you)
{
you.age = 24;
}
}
class myclass
{
public int age;
}
Don't confuse the variable and what the variable points to.
When you have:
MyClass myVar = new MyClass();
MyClass myVar2 = myVar;
That will create only a single instance of an object, but 2 variables pointing to it.
The same thing is happening to your parameter: you is a copy of the variable me, but both point to the same object. So when you modify you.age, you are also modifying me.age.
In your function, if you then did
you = new myClass();
only then would me and you refer to different objects. If you did this, me would still point to the original object.
If you added ref to the parameter you, then if you did
you = new myClass();
then the variable me would be updated to point to that same object.
For objects, you need to separate the variable from what the variable points to.
It's printing the right thing.
myclass is an object, and the default behavior is to pass the reference of the object in C#, so when you don't specify anything, you pass the reference.
If you declare struct myclass though, you'll have the behavior you want, because structs aren't references by default.
You're probably confusing this with C++ classes. In C#, classes are reference types, which means that whenever you have a variable of a type that's class, that variable doesn't hold the object itself, it holds only a reference to it (you can think of it as a pointer). So, when you pass your object into a method, you actually pass a reference to that object. This means the behavior you're observing is correct.
C# also supports value types (unlike e.g. Java), which you create by using struct instead of class. If you changed myclass into a srtuct, you would get the behavior you expected.
You are confusing value types and reference types.
public void addTwo(int a)
{
a += 2;
}
...
int a = 5;
addTwo(a);
Console.WriteLine(a); // will give "5";
public void addTwo(ref int a)
{
a += 2;
}
...
int a = 5;
addTwo(ref a);
Console.WriteLine(a); // will give "7";
For reference types (anything that is defined as class instead of struct, what you are passing on is a reference to the object, not a copy. So you are in fact changing the object.
You are sending an object to your function.
Not an atomic type or a struct, therefor it is sent by reference (this is how C# works), anything you change in this object in the function will also change in the original object because it is the same.
More information about passing parameters: http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx

Passing objects by reference or not in C#

Suppose I have a class like this:
public class ThingManager {
List<SomeClass> ItemList;
public void AddToList (SomeClass Item)
{
ItemList.Add(Item);
}
public void ProcessListItems()
{
// go through list one item at a time, get item from list,
// modify item according to class' purpose
}
}
Assume "SomeClass" is a fairly large class containing methods and members that are quite complex (List<>s and arrays, for example) and that there may be a large quantity of them, so not copying vast amounts of data around the program is important.
Should the "AddToList" method have "ref" in it or not? And why?
It's like trying to learn pointers in C all over again ;-) (which is probably why I am getting confused, I'm trying to relate these to pointers. In C it'd be "SomeClass *Item" and a list of "SomeClass *" variables)
Since SomeClass is a class, then it is automatically passed by reference to the AddToList method (or more accurately, its reference is passed by value) so the object is not copied. You only need to use the ref keyword if you want to re-assign the object the reference points to in the AddToList method e.g. Item = new SomeClass();.
Since SomeClass is a reference type, you do not need to use the "ref" keyword. If it were a value type, "ref" might be useful.
Think of out as a way of making a parameter work as a return value.
So these are very similar:
void Foo(out int result)
{
result = 5;
}
int Foo()
{
return 5;
}
And then think of ref as a way of allowing a parameter to be both an input and an output.
So in your example, if you declared your method:
public void AddToList(ref SomeClass Item)
Then the caller would have to write something like:
SomeClass i = null;
obj.AddToList(ref i);
This would be illegal, for example:
obj.AddToList(ref new SomeClass());
They would be forced to pass a variable name, rather than an expression, so that the AddToList method can store a value in the variable. By adding the ref prefix you are allowing your method to make the passed variable point to a different object.
If you ever need to use the original value of the parameter user ref. If not, use out. For reference:
http://www.yoda.arachsys.com/csharp/parameters.html
http://msdn.microsoft.com/en-us/library/0f66670z(VS.71).aspx

Can I pass parameters by reference in Java?

I'd like semantics similar to C#'s ref keyword.
Java is confusing because everything is passed by value. However for a parameter of reference type (i.e. not a parameter of primitive type) it is the reference itself which is passed by value, hence it appears to be pass-by-reference (and people often claim that it is). This is not the case, as shown by the following:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Will print Hello to the console. The options if you wanted the above code to print Goodbye are to use an explicit reference as follows:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Can I pass parameters by reference in
Java?
No.
Why ? Java has only one mode of passing arguments to methods: by value.
Note:
For primitives this is easy to understand: you get a copy of the value.
For all other you get a copy of the reference and this is called also passing by value.
It is all in this picture:
In Java there is nothing at language level similar to ref. In Java there is only passing by value semantic
For the sake of curiosity you can implement a ref-like semantic in Java simply wrapping your objects in a mutable class:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
#Override
public String toString() {
return value.toString();
}
#Override
public boolean equals(Object obj) {
return value.equals(obj);
}
#Override
public int hashCode() {
return value.hashCode();
}
}
testcase:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
From James Gosling in "The Java Programming Language":
"...There is exactly one parameter passing mode in Java - pass by value - and that keeps things simple.
.."
I don't think you can. Your best option might be to encapsulate the thing you want to pass "by ref" onto another class instance, and pass the (outer) class's reference (by value). If you see what I mean...
i.e. your method changes the internal state of the object it is passed, which is then visible to the caller.
Java is always pass by value.
When you pass a primitive it's a copy of the value, when you pass an object it's a copy of the reference pointer.
Another option is to use an array, e.g.
void method(SomeClass[] v) { v[0] = ...; }
but 1) the array must be initialized before method invoked, 2) still one cannot implement e.g. swap method in this way...
This way is used in JDK, e.g. in java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).
Check out my response in: http://stackoverflow.com/a/9324155/1676736
In there I used a simpler version of the wrapper class idea.
I don't like setters/getters as a standard. When there is no reason to bury a field I make it 'public'. Especially in something like this.
However, this would work for all but the primitive, or multi-parameter/type returns:
public class Ref<T> {
public T val;
}
Although, I suppose you could just add more type parameters. But I think that creating an inner static class fit-for-purpose would be easier:
public static class MyReturn {
public String name;
public int age;
public double salary;
}
this would be for use when you don't need it for other reasons.
MyReturn mRtn = new MyReturn();
public void myMethod(final MyReturn mRtn){
mRtn.name = "Fred Smith";
mRtn.age = 32;
mRtn.salary = 100000.00;
}
System.out.println(mRtn.name + " " +mRtn.age + ": $" + mRtn.salary);

Categories

Resources