C# Update out parameter in another function - c#

I have class that defines the following methods -
void DoAction1(out object result1)
{
// Do some work and set result1
}
void DoAction2(out object result2)
{
// Do some work and set result2
}
void ExecuteAllActions()
{
//Some more execution work happens here
// which may cause modifications to result1 and result2
}
Is there some way I can store a ref to the two out params and update them in ExecuteAllActions() function?

With the limited amount of information you have provided, all I can say is that you are doing it wrong. As a general rule, you never write a method with an out parameter and a void return type, since you can just return whatever object you would have assigned to the out parameter. This type of approach is much easier and simpler:
object DoAction1()
{
// Do some stuff and return a result object
}
object DoAction2()
{
// Do some stuff and return a result object
}
void ExecuteAllActions()
{
var actionResult1 = DoAction1();
var actionResult2 = DoAction2();
}

There is -- deliberately -- no way in the .NET type system to store a ref to a variable. This at a stroke avoids the problem of storing a reference to a variable whose lifetime has ended.
However, I note that a one-element array is an object that can be passed as a reference type, whose sole element is a variable that can be passed as ref or out. Obviously you can store a one-element array, pass it around as you like and so on.
That said, if you need to resort to tricks like this, something is probably wrong in the design. Try to make APIs that take values and return values, not take variables and mutate them.

Related

Alternatives to using ref keyword?

As a newbie I've read about the dangers of passing parameters with the ref keyword. I guess there's great potential to mess up code when a ref variable is modified in part of a program which then changes what happens elsewhere. Objects end up being very tightly coupled. (I recognize there may be places where ref is worthwhile.) What I don't yet know, and am asking about, are the alternatives.
In one program, for example, I create a generic list at startup, which I manipulate in the program's methods. In one method:
//a user is asked a question
//if the response is yes, the list is modified one way and the method returns true
//if the response is no, the list is modified a different way and the method returns false.
So the method returns a Boolean and I pass the list in as a ref. I have several similar methods, each asking users unique questions and then modifying the list in some way.
It seems like a typical alternative might be to bundle the list and a Boolean field into its own class. Somehow this seems like creating an object for nothing more than convenience, just to hold two pieces of data, with no connection to any real world entity.
So, how would you (pseudo)code a method that returns both a generic list and a Boolean value?
EDIT: Here's some actual code
private static bool AskExptQuestion(ref List<StatTest> testList)
{
Console.Write(Constants.ExptQText); //experimental groups?
string response = Console.ReadLine();
//if response==y, it's experimental
if (response == "y")
{
//so select all experimental
var q1List =
from test in testList
where test.isExperimental == true
select test;
//to copy resulting IEnumerable<List> (q1list) to generic List, must copy/cast IEnumerable to a List<t>
testList = q1List.ToList();
return true;
}
//and if response==n, it's not experimental
else
{
//so select all non-experimental
var q1List =
from test in testList
where test.isExperimental == false
select test;
testList = q1List.ToList();
return false;
}
}
Returning a list (or almost anything else, for that matter) along with its characteristic, such as a Boolean value, is a "poster child" of the ref/out feature. This pattern is used in several places in the standard .NET library:
Dictionary.TryGetValue uses this pattern, returning true or false depending on presence of the key in the dictionary, and setting a out to the return object
Integer.TryParse (and other numeric types) use this pattern, returning true when the parse is successful, and setting the value in a out parameter
The difference between ref and out is that ref gives your method an option to keep the old object/value or to supply a new one, while the out forces you to supply a new one before the method returns.
There is no point to create a new class simply to bundle two unrelated types together.
In addition, it is important to understand that modifications to method parameters can happen even in situations when a parameter is not passed by ref or out. When you pass an object of reference (i.e. class) type that is mutable, any modifications to the object done inside the method are visible in the caller.
The only difference when passing by ref or out is that you are allowed to replace the object itself with a new one, while passing a reference type without ref is restricted to mutating the incoming object itself.
From reading your example and comments, it sounds like you might just want the ability to apply some filters to a collection. Why not have your functions return the filters?
private static Predicate<StatTest> AskExptQuestion()
{
Console.Write(Constants.ExptQText); // experimental groups?
bool response = Console.ReadLine() == "y"; // maybe wrap this up in a function to read a yes/no answer
return t => t.isExperimental == response;
}
You might still need that bool return value, though, which can become an out parameter. It’s not clear what that’s for.
in c# paramaters are passed by value.
object types (classes) are implimented by a pointer to an instance in memory.
where passing an object to a method, the pointer is copied to the argument and he then points to the same instance.
if i have:
void foo(MyClass param)
{
param.x = 7;
}
and somewhere else i do:
MyClass obj = new MyClass();
obj.x = 5;
foo(obj);
then after the call to foo() the x property of obj is 7.
if foo is:
void foo(MyClass param)
{
param = new MyClass();
param = 7;
}
then my original obj will still have x equals to 5. this is because i ran over the instance that param was looking at.
now the "ref" keyword:
void foo(ref MyClass param)
{
param = new MyClass();
param = 7;
}
if i call like this:
MyClass obj = new MyClass();
obj.x = 5;
foo(ref obj);
in this combination my obj will be set to the new instance of MyClass and will have x equals 7. the ref means that the variable in the method is the same as the variable passed, and not just pointing to the same instance to start with.

C# Passing reference type directly vs out parameter

I have two methods:
public void A(List<int> nums)
{
nums.Add(10);
}
public void B(out List<int> nums)
{
nums.Add(10);
}
What is the difference between these two calls?
List<int> numsA = new List<int>();
A(numsA);
List<int> numsB = new List<int>();
B(out numsB);
In general, I am trying to understand the difference between passing reference types as-is or as out parameters.
In your example, method B will fail to compile, because an out parameter is considered to be uninitialized, so you have to initialize it before you can use it. Also, when calling a method with an out parameter, you need to specify the out keyword at the call site:
B(out numsB);
And you don't need to initialize the numbsB variable before the call, because it will be overwritten by the method.
Jon Skeet has a great article that explains the various ways to pass parameters: Parameter passing in C#
A non-ref, non-out parameter, like a local variable, denotes a storage location. If the storage location's type is a reference type, then the storage location holds a reference to an instance of that type.
Ref and out parameters, by contrast, hold a reference to a storage location. That storage location could be a local variable, a field, or an array element. In other words, ref and out parameters introduce another layer of indirection. If you have a reference-type ref or out parameter in a method, it therefore represents a reference to a reference to an object.
Why would you want a reference to a reference to an object? In case you need to modify the reference to the object (as opposed to modifying the object itself).
This is a useful technique in some narrow circumstances. For example, you might want to write a function that orders two queues depending on which has the smaller value on top:
void OrderQueues(ref Queue<int> a, ref Queue<int> b)
{
if (a.Peek <= b.Peek) return;
var temp = a;
a = b;
b = temp;
}
Out parameters are useful if you want to return more than one value from a method:
void OldestAndYoungest(IEnumerable<Person> people, out Person youngest, out Person oldest)
{
youngest = null;
oldest = null;
foreach (var person in people)
{
if (youngest == null || person.Age < youngest.Age)
youngest = person;
if (oldest == null || oldest.Age < person.Age)
oldest = person;
}
}
In my experience, ref and out parameters are fairly rare, and even rarer with reference types.
Note that a ref parameter must be initialized by the caller, while an out parameter must be initialized by the callee. If you never assign a value to the ref parameter, then it should probably be a "normal" parameter. If you never assign a value to an out parameter, as in your example, your code will not compile.
In version B, the function has direct access to the variable. It's like the 'ref' keyword, except that the variable must be assigned from within the function taking the parameter. It lets you return multiple values from a function. And the call syntax is 'B(out numsB);'
The out keyword causes arguments to be passed by reference. This is
similar to the ref keyword, except that ref requires that the variable
be initialized before being passed. To use an out parameter, both the
method definition and the calling method must explicitly use the out
keyword. For example:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier

Can I modify a passed method parameter

my gut feeling says I shouldn't do the following. I don't get any warnings about it.
void test(DateTime d)
{
d = d.AddDays(2);
//do some thing with d
}
or is this more proper
void test(DateTime d)
{
DateTime _d = d.AddDays(1);
//do some thing with _d
}
For some reason I have always handled passed parameters like in the second example.
But I am not sure if it's really nessesry...maybe it's just unnessary code.
I am not thinking that the calling method would be using the modified value.
anyone have any opinions
Changes to the value of a parameter are invisible to the caller, unless it's a ref or out parameter.
That's not the case if you make a change to an reference type object referred to by a parameter. For example:
public void Foo(StringBuilder b)
{
// Changes the value of the parameter (b) - not seen by caller
b = new StringBuilder();
}
public void Bar(StringBuilder b)
{
// Changes the contents of the StringBuilder referred to by b's value -
// this will be seen by the caller
b.Append("Hello");
}
Finally, if the parameter is passed by reference, the change is seen:
public void Baz(ref StringBuilder b)
{
// This change *will* be seen
b = new StringBuilder();
}
For more on this, see my article on parameter passing.
You can change it but the change will not go back to the caller.
If it is a ValueType -> The copy of object is sent
If it is a RefernceType -> Copy of Object reference will be sent by value. In this way properties of the object can be changed but not the reference itself - caller will not see the change anyway.
If it is sent ref -> Reference can be changed.
In C++ you can use const to prevent the change but C# does not have that. This is only to prevent the programmer by mistake try to change it - depending where the const is used.
If you want to be able to access the original value, use the second method.
If you don't care about the original value, you can use either one (I'd probably still use the second though).
Either way, you're not going to hurt anybody else's values (even if you re-assign the value, it won't make it back to the caller) in this case.

what is use of out parameter in c#

Can you please tell me what is the exact use of out parameter?
Related Question:
What is the difference between ref and out? (C#)
The best example of a good use of an out parameter are in the TryParse methods.
int result =-1;
if (!Int32.TryParse(SomeString, out result){
// log bad input
}
return result;
Using TryParse instead of ParseInt removes the need to handle exceptions and makes the code much more elegant.
The out parameter essentially allows for more than one return values from a method.
The out method parameter keyword on a
method parameter causes a method to
refer to the same variable that was
passed into the method. Any changes
made to the parameter in the method
will be reflected in that variable
when control passes back to the
calling method.
Declaring an out method is useful when
you want a method to return multiple
values. A method that uses an out
parameter can still return a value. A
method can have more than one out
parameter.
To use an out parameter, the argument
must explicitly be passed to the
method as an out argument. The value
of an out argument will not be passed
to the out parameter.
A variable passed as an out argument
need not be initialized. However, the
out parameter must be assigned a value
before the method returns.
An Example:
using System;
public class MyClass
{
public static int TestOut(out char i)
{
i = 'b';
return -1;
}
public static void Main()
{
char i; // variable need not be initialized
Console.WriteLine(TestOut(out i));
Console.WriteLine(i);
}
}
http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx
Out parameters are output only parameters meaning they can only passback a value from a function.We create a "out" parameter by preceding the parameter data type with the out modifier. When ever a "out" parameter is passed only an unassigned reference is passed to the function.
using System;
class ParameterTest
{
static void Mymethod(out int Param1)
{
Param1=100;
}
static void Main()
{
int Myvalue=5;
MyMethod(Myvalue);
Console.WriteLine(out Myvalue);
}
}
Output of the above program would be 100 since the value of the "out" parameter is passed back to the calling part. Note
The modifier "out" should precede the parameter being passed even in the calling part. "out" parameters cannot be used within the function before assigning a value to it. A value should be assigned to the "out" parameter before the method returns.
Besides allowing you to have multiple return values, another use is to reduce overhead when copying a large value type to a method. When you pass something to a method, a copy of the value of that something is made. If it's a reference type (string for example) then a copy of the reference (the value of a reference type) is made. However, when you copy a value type (a struct like int or double) a copy of the entire thing is made (the value of a value type is the thing itself). Now, a reference is 4 bytes (on 32-bit applications) and an int is 4 bytes, so the copying is not a problem. However, it's possible to have very large value types and while that's not recommended, it might be needed sometimes. And when you have a value type of say, 64 bytes, the cost of copying it to methods is prohibitive (especially when you use such a large struct for performance reasons in the first place). When you use out, no copy of the object is made, you simply refer to the same thing.
public struct BigStruct
{
public int A, B, C, D, E, F, G, H, J, J, K, L, M, N, O, P;
}
SomeMethod(instanceOfBigStruct); // A copy is made of this 64-byte struct.
SomeOtherMethod(out instanceOfBigStruct); // No copy is made
A second use directly in line with this is that, because you don't make a copy of the struct, but refer to the same thing in the method as you do outside of the method, any changes made to the object inside the method, are persisted outside the method. This is already the case in a reference type, but not in value types.
Some examples:
public void ReferenceExample(SomeReferenceType s)
{
s.SomeProperty = "a string"; // The change is persisted to outside of the method
}
public void ValueTypeExample(BigStruct b)
{
b.A = 5; // Has no effect on the original BigStruct that you passed into the method, because b is a copy!
}
public void ValueTypeExampleOut(out BigStruct b)
{
b = new BigStruct();
b.A = 5; // Works, because you refer to the same thing here
}
Now, you may have noticed that inside ValueTypeExampleOut I made a new instance of BigStruct. That is because, if you use out, you must assign the variable to something before you exit the method.
There is however, another keyword, ref which is identical except that you are not forced to assign it within the method. However, that also means you can't pass in an unassigned variable, which would make that nice Try.. pattern not compile when used with ref.
int a;
if(TrySomething(out a)) {}
That works because TrySomething is forced to assign something to a.
int a;
if(TrySomething(ref a)) {}
This won't work because a is unassigned (just declared) and ref requires that you only use it with an assigned variable.
This works because a is assigned:
int a = 0;
if(TrySomething(ref a)) {}
However, in both cases (ref and out) any changes made to a within the TrySomething method are persisted to a.
As I already said, changes made to a reference type are persisted outside the method in which you make them, because through the reference, you refer to the same thing.
However, this doesn't do anything:
public void Example(SomeReferenceType s)
{
s = null;
}
Here, you just set the copy of a reference to s to null, which only exists within the scope of the method. It has zero effect on whatever you passed into the method.
If you want to do this, for whatever reason, use this:
public void Example1(ref SomeReferenceType s)
{
s = null; // Sets whatever you passed into the method to null
}
I think this covers all use-cases of out and ref.
from http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx
One way to think of out parameters is that they are like additional return values of a method. They are very convenient when a method returns more than one value, in this example firstName and lastName. Out parameters can be abused however. As a matter of good programming style if you find yourself writing a method with many out parameters then you should think about refactoring your code. One possible solution is to package all the return values into a single struct.
In contrast ref parameters are considered initially assigned by the callee. As such, the callee is not required to assign to the ref parameter before use. Ref parameters are passed both into and out of a method.
The typical use case is a method that needs to return more than one thing, so it can't just use the return value. Commonly, the return value is used for a success flag while the out parameter(s) sets values when the method is successful.
The classic example is:
public bool TryGet(
string key,
out string value
)
If it returns true, then value is set. Otherwise, it's not. This lets you write code such as:
string value;
if (!lookupDictionary.TryGet("some key", out value))
value = "default";
Note that this doesn't require you to call Contains before using an indexer, which makes it faster and cleaner. I should also add that, unlike the very similar ref modifier, the compiler won't complain if the out parameter was never initialized.
In simple words pass any variable to the function by reference so that any changes made to that variable in side that function will be persistent when function returns from execution.
Jon Skeet describes the different ways of passing parameters in great detail in this article. In short, an out parameter is a parameter that is passed uninitialized to a method. That method is then required to initialize the parameter before any possible return.
generally we cannot get the variables inside a function if we don't get by a return value.
but use keyword "out" we can change it value by a function.

In c# , when sending a parameter to a method, when should we use "ref" and when "out" and when without any of them?

In c# , when sending a parameter to a method, when should we use "ref" and when "out" and when without any of them?
In general, you should avoid using ref and out, if possible.
That being said, use ref when the method might need to modify the value. Use out when the method always should assign something to the value.
The difference between ref and out, is that when using out, the compiler enforces the rule, that you need to assign something to the out paramter before returning. When using ref, you must assign a value to the variable before using it as a ref parameter.
Obviously, the above applies, when you are writing your own methods. If you need to call methods that was declared with the ref or out modifiers on their parameters, you should use the same modifier before your parameter, when calling the method.
Also remember, that C# passes reference types (classes) by reference (as in, the reference is passed by value). So if you provide some method with a reference type as a parameter, the method can modify the data of the object; even without ref or out. But it cannot modify the reference itself (as in, it cannot modify which object is being referenced).
They are used mainly to obtain multiple return values from a method call. Personally, I tend to not use them. If I want multiple return values from a method then I'll create a small class to hold them.
ref and out are used when you want something back from the method in that parameter. As I recall, they both actually compile down to the same IL, but C# puts in place some extra stuff so you have to be specific.
Here are some examples:
static void Main(string[] args)
{
string myString;
MyMethod0(myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod0(string param1)
{
param1 = "Hello";
}
The above won't compile because myString is never initialised. If myString is initialised to string.Empty then the output of the program will be a empty line because all MyMethod0 does is assign a new string to a local reference to param1.
static void Main(string[] args)
{
string myString;
MyMethod1(out myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod1(out string param1)
{
param1 = "Hello";
}
myString is not initialised in the Main method, yet, the program outputs "Hello". This is because the myString reference in the Main method is being updated from MyMethod1. MyMethod1 does not expect param1 to already contain anything, so it can be left uninitialised. However, the method should be assigning something.
static void Main(string[] args)
{
string myString;
MyMethod2(ref myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod2(ref string param1)
{
param1 = "Hello";
}
This, again, will not compile. This is because ref demands that myString in the Main method is initialised to something first. But, if the Main method is changed so that myString is initialised to string.Empty then the code will compile and the output will be Hello.
So, the difference is out can be used with an uninitialised object, ref must be passed an initialised object. And if you pass an object without either the reference to it cannot be replaced.
Just to be clear: If the object being passed is a reference type already then the method can update the object and the updates are reflected in the calling code, however the reference to the object cannot be changed. So if I write code like this:
static void Main(string[] args)
{
string myString = "Hello";
MyMethod0(myString);
Console.WriteLine(myString);
Console.ReadLine();
}
public static void MyMethod0(string param1)
{
param1 = "World";
}
The output from the program will be Hello, and not World because the method only changed its local copy of the reference, not the reference that was passed in.
I hope this makes sense. My general rule of thumb is simply not to use them. I feel it is a throw back to pre-OO days. (But, that's just my opinion)
(this is supplemental to the existing answers - a few extra considerations)
There is another scenario for using ref with C#, more commonly seen in things like XNA... Normally, when you pass a value-type (struct) around, it gets cloned. This uses stack-space and a few CPU cycles, and has the side-effect that any modifications to the struct in the invoked method are lost.
(aside: normally structs should be immutable, but mutable structs isn't uncommon in XNA)
To get around this, it is quite common to see ref in such programs.
But in most programs (i.e. where you are using classes as the default), you can normally just pass the reference "by value" (i.e. no ref/out).
Another very common use-case of out is the Try* pattern, for example:
string s = Console.ReadLine();
int i;
if(int.TryParse(s, out i)) {
Console.WriteLine("You entered a valid int: " + i);
}
Or similarly, TryGetValue on a dictionary.
This could use a tuple instead, but it is such a common pattern that it is reasonably understood, even by people who struggle with too much ref/out.
Very simple really. You use exactly the same keyword that the parameter was originally declared with in the method. If it was declared as out, you have to use out. If it was declared as ref, you have to use ref.
In addition to Colin's detailed answer, you could also use out parameters to return multiple values from one method call. See for example the method below which returns 3 values.
static void AssignSomeValues(out int first, out bool second, out string third)
{
first = 12 + 12;
second = false;
third = "Output parameters are okay";
}
You could use it like so
static void Main(string[] args) {
int i;
string s;
bool b;
AssignSomeValues(out i, out b, out s);
Console.WriteLine("Int value: {0}", i);
Console.WriteLine("Bool value: {0}", b);
Console.WriteLine("String value: {0}", s);
//wait for enter key to terminate program
Console.ReadLine(); }
Just make sure that you assign a valid value to each out parameter to avoid getting an error.
Try to avoid using ref. Out is okay, because you know what will happen, the old value will be gone and a new value will be in your variable even if the function failed. However, just by looking at the function you have no idea what will happen to a ref parameter. It may be the same, modified, or an entirely new object.
Whenever I see ref, I get nervous.
ref is to be avoided (I beleive there is an fx-cop rule for this also) however use ref when the object that is reference may itself changed. If you see the 'ref' keyword you know that the underlying object may no longer be referenced by the same variable after the method is called.

Categories

Resources