can anyone suggest me the exact use of out keyword as a paramter, and how its connected for returning multiple values from the function, as in this POST, i am confused with out variable with normal variable. can anyone help me for this.
This is frequently confusing, and I think the MSDN documentation actually is a bit "clear only if already known". That is, it is correct, but it really only makes sense if you already understand the concept.
Here's how I think of it.
A regular parameter makes a copy of the value of the argument. When you say:
static int M(int z) { z = z + 1; return z; }
...
int x = 123;
int y = M(x);
That is just like you said:
int x = 123;
int z = x; // make a copy of x
z = z + 1;
int y = z;
A ref or out parameter make an alias for an existing variable. When you say
static void N(ref int q) { q = q + 1; }
...
int x = 123;
N(x);
That is the same as saying:
int x = 123;
// MAGIC: q is now an another name for variable x
q = q + 1;
q and x are two different names that refer to the same variable. Incrementing q also increments x because they are the same. z and x in the previous example are two different names that refer to two different variables. Incrementing z does not change x.
Summing up: "out" and "ref" just mean "do not make a new variable; rather, temporarily make a second name for an existing variable".
Is that now clear?
UPDATE: I did not say what the difference between "out" and "ref" is. The difference is simple. On the "caller" side, a "ref" must be a definitely assigned variable before the method is called. An "out" need not be. On the "callee" side, a "ref" may be read before it is written to, but an "out" must be written to before it is read. Also, an "out" must be written to before control leaves the method normally.
MSDN documentation already does a great job explaining this:
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:
class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
It's very frequently used in a pattern that "tries" to get a value, something like:
int result;
if(Int32.TryParse("123", out result))
{
Console.WriteLine(result + 1);
}
out keyword should be used when you want to:
a) Allow your function to modify specific variable from calling code stack AND
b) enforce setting this variable value inside your function
MSDN is always a good place to start
In most languages c# included you can pass values in 2 ways, by value, by reference.
by value gives the method a copy of your data, so changing the data wont have any effect on the original data
by reference essentially gives the method the memory address of your data, so if the method modifies the data, it changes the original.
Out is a special type of ref, in that you do not need to initialise the variable before you call the method, it can be called with null being passed in. and it MUST be set by the method.
Another way you can think of it (from the outside code's point of view) is:
val = read only
ref = read/write
out = write only.
http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
out keyword is good if you want to return multiple values of pre-defined types (for example an int, a List<string> and a DateTime), and you don't want to create a new class just for this purpose.
Ok,
let look at the usual pattern for this kind of function - the TrySomething.
Suppose you have a function that might succeed giving you an value or not but you don't won't to use an exception for this because you don't want the overhead or it's a common trait.
Then you normaly return true if the method suceeded and false if not. But where would you put your outputvalue to?
One possible answer is using an out parameter like this:
bool TrySomething(MyInputType input, out MyOutputType output)
{
output = default(MyOutputType);
/* ... Try getting the answer ... */
if (!successful)
return false;
output = successfulOutput;
return true;
}
Remark:
Or you might consider using a Tuple<bool,MyOutputType> and indeed F# interpretes the pattern above as resulting in such a tuple by itself.
Related
Basic manuals on C# state that to change a value type when passed to another method you must use the out or ref keywords, etc.
For example:
int Loop(int counter)
{
return(++counter);
}
void ClickIt ()
{
int count = 0;
for (int c1 = 0; c1 < 10; c1++)
{
count = Loop(count);
Console.Writeline(count);
}
}
Here, ClickIt outputs the following result: 1, 2, 3, 4, ... 10
In the example, count (a value type), which is being passed from the method ClickIt to the method Loop without out or ref, is being changed in Loop. And Loop then returns count to the calling method ClickIt which picks up the change to count.
So, my question is: When is a value type, when passed as an argument to another method, required to use out or ref so that the value can be changed?
You have an incorrect understanding of the meaning of "ref", and you are also mixing up values and variables. These are common mistakes.
Let's go back to basics.
A variable is a storage location which can contain a value.
Let's simplify your program:
int M(int x)
{
x++;
return x;
}
void N()
{
int y = 0;
y = M(y);
}
If N is called, what happens?
Imagine a variable is a drawer that can contain a sheet of paper. We make a drawer and label it y. In y we put a piece of paper that says "0". Now we call M(y). What happens?
We make a new drawer labeled "x" and we make a photocopy of the piece of paper in "y". We put the copy in drawer x. y contains a piece of paper that says 0, and x contains a different piece of paper that also contains 0.
Now in M we increment x. What happens? We make a new piece of paper that says 1, throw away the old one, and put the new one in drawer x.
Now we make a photocopy of the value in x, so we have another piece of paper that says 1. When M returns we put that piece of paper into y and throw away the 0 that is already in there.
Did M modify y? No. M only modified x. N modified y, twice. Once when y was created, and once after M returned.
Notice that we made two copies. First, we made a copy of y on the way in to M and copied it to x, and then we made a copy of x on the way out and copied it to y.
Now suppose we have
void P(ref int b)
{
b++;
}
void Q()
{
int c = 0;
P(ref c);
}
We run Q. What happens? We make a drawer called c and put a piece of paper in it that says "0". What happens when we call P? Something different. This time we make a drawer called b and put a piece of paper in it that says "don't use this drawer! Every time you try to use this drawer, use c instead!" That is, b refers its behaviour to c.
Now P tries to increment b. It tries to get a value out of b, but discovers that b says no, use c. So it looks in c, finds 0, makes a new piece of paper that says 1, replaces the contents of b -- no, wait, we need to replace the contents of c -- with 1, and returns. So c is updated to 1.
Does it make sense why these two things are different? The first is called copy in, copy out because we make a photocopy of y on the way in to M, and a copy of x on the way out. The second is called by reference because b refers its behaviour to c; no values are copied.
In your sample you actually do not modify passed count variable.
When it's passed, a copy inside a Loop function scope is being created. Then modification done, you return in back and set to your count variable.
Actually, the purpose of:
ref - is that variable should be already initialized before passing into function. And copy is not created inside. You modify passed variable directly. As result - you don't need to return modified value and set it back to your variable.
out - it does not require passed variable to be initialized before passing into your function. But it actually MUST be initialized inside that function.
Hope that's all.
Long comment...
Your code could be confusing - make sure to separate result of function from parameter:
void ClickIt ()
{
int count =0;
for (int c1 =0; c1 < 10; c1++)
{
var resultCount = Loop(count);
Console.Writeline("Result:{0}, count:{1}", resultCount, count);
}
}
Answer (opinion based) - you should almost never use out/ref - it is much harder to reason about than return values. Such functions also are hard to use in LINQ/lambda expression due to need of arguments to be variables.
Common case when it somewhat acceptable is when function returns more than one result (like TryParse), but consider if some other return type (i.e. nullable int?) would work too.
I'm trying to get make method in which I can assign values to multiple variables. I don't know how many variables I will have, but I know their type. The variables can all be of different types though.
I have googled quite a bit about this, and am fairly sure that this can't be done with managed code. (Correct me if I'm wrong though)
I don't know much (read: anything) about unsafe code. Can it be done that way? Maybe pass in an array of pointers to the variables I want to initialise and do it that way?
I am basically looking for a way to pass an arbitrary number of mixed type variables to a method and assign their values inside the method... Is it pie in the sky?
EDIT 1:
Here is some code which I hope illustrates what I would like to achieve:
private void SomeMethod()
{
string a = string.empty;
int b = 0;
double c = 0;
object[] testObject = new object[] { b, c };
SetVariables(ref testObject);
}
public static void SetVariables(ref object[] Variables)
{
for (int i = 0; i < Variables.Length; i++)
Variables[i] = // The value the variable needs to have
}
After SetVariables has executed, a, b and c would be say:
a = "Some text"
b = 123
c = 1564.653
I am looking for a way to access the variables passed in as the parameter to SetVariables and modify their value. I guess that would mean accessing their storage location in memory, hence my thinking that I might need pointers?
EDIT 2:
My question here should give a better indication of the context in which I am trying to do this.
I will only be dealing with basic types: string, int, double and bool for the variables I want to assign to.
The data I am assigning from is in text format and has a variable number of fields. Each field should map to one of the input variable in the order in which the variables are passed in. If the order does not match there will be a misasignment at best or a type error at worst, but it is up to the user to make sure that the variables match the data.
What you are trying to do doesn't work well in C#. It is really a language thing, not a "managed vs un-managed" thing.
It usually doesn't come up that much, because in your sample code, you do know that you have 2 variables. You had to type them to enter them into the array.
If SetVariables() is going to be called from a lot of places in the code with different numbers of parameters, you could make a bunch of overloads of the method (with 1 parameter, 2 parameters, 3 parameters, etc).
But really to be honest, typically when you run into this case it is because you are doing something in an un-wise way.
Thinking more about it, how would the line:
Variables[i] = // The value the variable needs to have
would be expected to work in this scenario. How does it know what to set an arbitrary variable to, since it can be of any type? Also, what stops it from messing up the variable assignments if I change the call from passing in variable b, c to reversing them c, b?
Logically, it starts to fall apart.
I guess what I'm trying to say is that C# doesn't support that very well, but it typically doesn't need to, because it rarely makes sense.
Trying to think of a working solution anyway; I would just have SetVariables just return the values, but not take in the parameters. It should be the other function's job to assign its variables. If you need to know the types, then just pass the types:
public object[] GetValues(params Type types)
{
var result = new object[types.length];
for (int i = 0; i < types.length; i++)
{
if(types[i] == typeof(string))
result[i] = "foo";
if(types[i] == typeof(int))
result[i] = -1;
}
return result;
}
public void DoStuff()
{
var data = GetValues(typeof(string), typeof(int), typeof(string));
string foo1 = (string)data[0];
int someNumber = (int)data[1];
string foo2 = (string)data[2];
}
Its ugly, but it works...
Here is an example adapted from this answer to a similar question, unfortunately your problem is a little difficult to solve and there really isn't a simple way to accomplish what you want.
private static void SomeMethod() {
string a = string.Empty;
int b = 0;
double c = 0;
SetVariables(x => a = (string)x
, x => b = (int)x
, x => c = (double)x);
Console.WriteLine("a: {0}\nb: {1}\nc: {2}", a, b, c);
}
public static void SetVariables(params Action<object>[] setters) {
var tokens = new object[] { "Hello", 10, 14.235 };
for (int i = 0; i < setters.Length; i++)
setters[i](tokens[i]); // Assumed this is read and initialized properly
}
I'll admit this has a bit of a smell to it, but since you really have to account for a variable input it should get you closer to what you want without adding an excessive amount of complexity.
I think you are pretty close to the answer yourself. Assuming that the value assigned to the variable is only based off what type it is then assuming you use the code you posted above you can compare the value type with a typeof() check during your for loop:
if(Variables[i].GetType() == typeof(int)){
//...do stuff
}
//etc...until you have an if for each data type you expect you might find
here is a link to the typeof documentation
I'm assuming you have looked at how to use reference types but just in case look here
I've been investigating the out keyword in C# after reading the section about it in C# in Depth. I cannot seem to find an example that shows why the keyword is required over just assigning the value of a return statement. For example:
public void Function1(int input, out int output)
{
output = input * 5;
}
public int Function2(int input)
{
return input * 5;
}
...
int i;
int j;
Function1(5, out i);
j = Function2(5);
Both i and j now have the same value. Is it just the convenience of being able to initialize without the = sign or is there some other value derived that I'm not seeing? I've seen some similar answers mentioning that it shifts responsibility for initialization to the callee here. But all that extra instead of just assigning a return value and not having a void method signature?
Usually out is used for a method that returns something else, but you still need to get a different value from the method.
A good example is Int32.TryParse(input, out myVar) it will return true if it was successful and false otherwise. You can get the converted int via the out parameter.
int myOutVar;
if (Int32.TryParse("2", out myOutVar))
{
//do something with the int
}else{
//Parsing failed, show a message
}
The out / ref keywords in C# should only be used when you need to return multiple values. Even then you should first consider using a container type (such as Tuple) to return multiple values before you revert to out / ref. Whenever you're returning a single value it should just be returned.
A lot of times, using out can help by giving you a slight performance gain.
Consider the TryGetValue method on IDictionary (say myDictionary is an IDictionary<string, string>) Rather than doing this:
string value = String.Empty;
if (myDictionary.ContainsKey("foo"))
{
value = myDictionary["foo"];
}
Both ContainsKey and the indexer need to look up the key in the dictionary, but you can avoid this double-lookup on the positive case by going:
string value;
if (!myDictionary.TryGetValue("foo", out value))
{
value = String.Empty;
}
IMO, that's a decent reason for using out parameters.
Unfortunately we cannot do something like below in C#:
a,b = func(x,y,z);
something that we do in Python or other languages. out kind of overcomes that.
F# has overcome this with tuples I believe.
PS: Returning multiple values from a function might not be good always. Tiny types are good most of the times - http://www.martinfowler.com/bliki/DataClump.html
For example, Int32.TryParse returns boolean if it parsed correctly and with the out parameter changes the value. If the parsed value is 0 and it returns true it means the value you sent to parse was 0. If it returns false then the parser failed.
Some of it is for clarity. Take the TryParse() methods, like
Int32.TryParse("3", out myInt);
This returns a bool that indicates whether the string was able to be parsed into an int.
If you just had
Int32.TryParse("3", myInt);
What happens when that's called? Is myInt assigned? Does TryParse return an int?
It's not readily apparent. But if I have an out parameter, then I know that the value is getting assigned, and that the return is something else.
Basically you do something like (my database read)
if (ReadSingle<UserRecord>(cmd, out user))
Cache.Insert(cacheId, user, null,
DateTime.MaxValue, TimeSpan.FromMinutes(3));
Or else you do something like:
user = ReadSingle<UserRecord>(cmd);
if(null != user)
// Cache.Insert ...
It simplifies the code a little to use a boolean result (that a record was read from the database) and get the actual record into the variable via the out keyword.
I'm getting the above error and unable to resolve it.
I googled a bit but can't get rid of it.
Scenario:
I have class BudgetAllocate whose property is budget which is of double type.
In my dataAccessLayer,
In one of my classes I am trying to do this:
double.TryParse(objReader[i].ToString(), out bd.Budget);
Which is throwing this error:
Property or indexer may not be passed as an out or ref parameter at
compile time.
I even tried this:
double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget);
Everything else is working fine and references between layers are present.
Others have given you the solution, but as to why this is necessary: a property is just syntactic sugar for a method.
For example, when you declare a property called Name with a getter and setter, under the hood the compiler actually generates methods called get_Name() and set_Name(value). Then, when you read from and write to this property, the compiler translates these operations into calls to those generated methods.
When you consider this, it becomes obvious why you can't pass a property as an output parameter - you would actually be passing a reference to a method, rather than a reference to an object a variable, which is what an output parameter expects.
A similar case exists for indexers.
This is a case of a leaky abstraction. A property is actually a method, the get and set accessors for an indexer get compiled to get_Index() and set_Index methods. The compiler does a terrific job hiding that fact, it automatically translates an assignment to a property to the corresponding set_Xxx() method for example.
But this goes belly up when you pass a method parameter by reference. That requires the JIT compiler to pass a pointer to the memory location of the passed argument. Problem is, there isn't one, assigning the value of a property requires calling the setter method. The called method cannot tell the difference between a passed variable vs a passed property and can thus not know whether a method call is required.
Notable is that this actually works in VB.NET. For example:
Class Example
Public Property Prop As Integer
Public Sub Test(ByRef arg As Integer)
arg = 42
End Sub
Public Sub Run()
Test(Prop) '' No problem
End Sub
End Class
The VB.NET compiler solves this by automatically generating this code for the Run method, expressed in C#:
int temp = Prop;
Test(ref temp);
Prop = temp;
Which is the workaround you can use as well. Not quite sure why the C# team didn't use the same approach. Possibly because they didn't want to hide the potentially expensive getter and setter calls. Or the completely undiagnosable behavior you'll get when the setter has side-effects that change the property value, they'll disappear after the assignment. Classic difference between C# and VB.NET, C# is "no surprises", VB.NET is "make it work if you can".
you cannot use
double.TryParse(objReader[i].ToString(), out bd.Budget);
replace bd.Budget with some variable.
double k;
double.TryParse(objReader[i].ToString(), out k);
Possibly of interest - you could write your own:
//double.TryParse(, out bd.Budget);
bool result = TryParse(s, value => bd.Budget = value);
}
public bool TryParse(string s, Action<double> setValue)
{
double value;
var result = double.TryParse(s, out value);
if (result) setValue(value);
return result;
}
Place the out parameter into a local variable and then set the variable into bd.Budget:
double tempVar = 0.0;
if (double.TryParse(objReader[i].ToString(), out tempVar))
{
bd.Budget = tempVar;
}
Update: Straight from MSDN:
Properties are not variables and
therefore cannot be passed as out
parameters.
This is a very old post, but I'm ammending the accepted, because there is an even more convienient way of doing this which I didn't know.
It's called inline declaration and might have always been available (as in using statements) or it might have been added with C#6.0 or C#7.0 for such cases, not sure, but works like a charm anyway:
Inetad of this
double temp;
double.TryParse(objReader[i].ToString(), out temp);
bd.Budget = temp;
use this:
double.TryParse(objReader[i].ToString(), out double temp);
bd.Budget = temp;
So Budget is a property, correct?
Rather first set it to a local variable, and then set the property value to that.
double t = 0;
double.TryParse(objReader[i].ToString(), out t);
bd.Budget = t;
Usually when I'm trying to do this it's because I want to set my property or leave it at the default value. With the help of this answer and dynamic types we can easily create a string extension method to keep it one lined and simple.
public static dynamic ParseAny(this string text, Type type)
{
var converter = TypeDescriptor.GetConverter(type);
if (converter != null && converter.IsValid(text))
return converter.ConvertFromString(text);
else
return Activator.CreateInstance(type);
}
Use like so;
bd.Budget = objReader[i].ToString().ParseAny(typeof(double));
// Examples
int intTest = "1234".ParseAny(typeof(int)); // Result: 1234
double doubleTest = "12.34".ParseAny(typeof(double)); // Result: 12.34
decimal pass = "12.34".ParseAny(typeof(decimal)); // Result: 12.34
decimal fail = "abc".ParseAny(typeof(decimal)); // Result: 0
string nullStr = null;
decimal failedNull = nullStr.ParseAny(typeof(decimal)); // Result: 0
Optional
On a side note, if that's an SQLDataReader you may also make use of GetSafeString extension(s) to avoid null exceptions from the reader.
public static string GetSafeString(this SqlDataReader reader, int colIndex)
{
if (!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
public static string GetSafeString(this SqlDataReader reader, string colName)
{
int colIndex = reader.GetOrdinal(colName);
if (!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
Use like so;
bd.Budget = objReader.GetSafeString(i).ParseAny(typeof(double));
bd.Budget = objReader.GetSafeString("ColumnName").ParseAny(typeof(double));
I had the same problem (5 minutes ago) and I solved it using old style properties with getter and setter, whose use variables.
My code:
public List<int> bigField = new List<int>();
public List<int> BigField { get { return bigField; } set { bigField = value; } }
So, I just used bigField variable. I'm not the programmer, if I misunderstood the question, I'm really sorry.
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.