Difference between revisions of "Parameters - Global Variables"
(→Basic Example) |
(→Lots) |
||
Line 24: | Line 24: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | === Scope === | + | === Argument Scope === |
parameters passed to a function are passed as copies of their actual values and hence values sent and used as arguments by method are from a memory point of view different to the values actually passed. Because of this any changes made to arguments passed to a method have no affect on the value of the actual variable they're passed from, for example: | parameters passed to a function are passed as copies of their actual values and hence values sent and used as arguments by method are from a memory point of view different to the values actually passed. Because of this any changes made to arguments passed to a method have no affect on the value of the actual variable they're passed from, for example: | ||
Line 45: | Line 45: | ||
test += 1; | test += 1; | ||
Console.WriteLine(test); // Outputs 2; | Console.WriteLine(test); // Outputs 2; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | </tabber> | ||
+ | |||
+ | As the example above dictates Any from the moment the integer test1 is passed to the method DoSomething the argument used by the method is intrisically different to the variable passed to it. There are two way to circumvent this problem and attempt to save changes made by a method to a variable. | ||
+ | |||
+ | * One Method would be to declare the variable in a more globally accessible scope in relation to the two methods and edit them referencing directly to this variable declaration, for Example: | ||
+ | |||
+ | <tabber> | ||
+ | C#= | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | |||
+ | class Program { | ||
+ | public static void DoSomething() { | ||
+ | // int no longer passed as argument | ||
+ | testInt += 1; | ||
+ | } | ||
+ | |||
+ | public static void Main(String[] Args) { | ||
+ | testInt = 1; | ||
+ | Console.WriteLine(testInt); // Outputs 1; | ||
+ | |||
+ | DoSomething(); // testInt not passed as arg | ||
+ | Console.WriteLine(testInt); // Outputs 2; | ||
+ | |||
+ | testInt += 1; | ||
+ | Console.WriteLine(testInt); // Outputs 3; | ||
+ | } | ||
+ | |||
+ | public static int testInt; // int declared in same scope as two methods. | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | </tabber> | ||
+ | |||
+ | While this method has it's upside it's difficult to apply to an existing complex algorithm and doesn't actually involve any parameter passing, making it inefficient for the task it's trying to accomplish. On the other hand | ||
+ | |||
+ | * Another option would be to use the ref keyword in the parameter portion of the method, allowing the value being passed as an argument to be passed as a reference to the memory location of the actual variable instead of as a copy of the value stored at said memory location. | ||
+ | |||
+ | <tabber> | ||
+ | C#= | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | |||
+ | class Program { | ||
+ | public static void DoSomething(ref int intTestRef) { | ||
+ | intTestRef += 1; | ||
+ | } | ||
+ | |||
+ | public static void Main(String[] Args) { | ||
+ | int test = 1; | ||
+ | Console.WriteLine(test); // Outputs 1; | ||
+ | |||
+ | DoSomething(ref test); // passed as reference | ||
+ | Console.WriteLine(test); // Outputs 2; | ||
+ | |||
+ | test += 1; | ||
+ | Console.WriteLine(test); // Outputs 3; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | </tabber> | ||
+ | |||
+ | This method is the preferred solution to keeping changes to passed parameters. | ||
+ | |||
+ | === Unlimited Parameters === | ||
+ | To pass as many arguments as you desire to a method, you can use the params keyword to set a method to accept as many parameters as given to it without throwing an exception, for example: | ||
+ | |||
+ | <tabber> | ||
+ | C#= | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | |||
+ | class Program { | ||
+ | public static String DoSomething(String seperator, params String[] args) { | ||
+ | return String.Join(seperator, args); | ||
+ | } | ||
+ | |||
+ | public static void Main(String[] Args) { | ||
+ | Console.WriteLine(DoSomething(" ", "BLARG", "BLARG2", "BLARG3")); // Outputs "BLARG BLARG2 BLARG3" | ||
+ | Console.WriteLine(DoSomething(" ", "BLARG")); // Outputs "BLARG" | ||
+ | Console.WriteLine(DoSomething("BLARG", " ", " ", " ")); // Outputs " BLARG BLARG " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | </tabber> | ||
+ | |||
+ | === Optional Parameters & nullable parameters === | ||
+ | Parameters dont have to be mandatory, if required you can give a parameter a default value or mark it as nullable meaning it will be null unless something is passed to it. for example: | ||
+ | |||
+ | <tabber> | ||
+ | C#= | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | |||
+ | class Program { | ||
+ | public static String DoSomething(String value = "BLARG") { // optional Parameter value | ||
+ | return value; | ||
+ | } | ||
+ | |||
+ | public static void Main(String[] Args) { | ||
+ | Console.WriteLine(DoSomething()) // Outputs "BLARG"; Note No Parameter Passed | ||
+ | Console.WriteLine(DoSomething("YOZIT")) // Outputs "YOZIT"; Note Parameter Passed | ||
+ | Console.WriteLine(DoSomething(value : "BLARG")) // Outputs "BLARG"; Note Parameter Passed as named argument | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | </tabber> | ||
+ | |||
+ | this is an example of optional parameter passing, but such capabilty doesn't come without costs, for example optional parameters must be placed after mandatory parameters and must have an acceptable value, hence the following is invalid: | ||
+ | |||
+ | <tabber> | ||
+ | C#= | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | public static DoSomething(String value = "BLARG", int value2) {} | ||
+ | </syntaxhighlight> | ||
+ | </tabber> | ||
+ | |||
+ | <tabber> | ||
+ | C#= | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | public static DoSomething(String value = 5) {} | ||
+ | </syntaxhighlight> | ||
+ | </tabber> | ||
+ | |||
+ | To end things here I will explain nullable types, these are parameters which may or may not be used by a given method but do not have to have a set value, hence making them null. Nullable types come with a hefty HasValue attribute to let you now wether a given nullable is actually null or not, for Example: | ||
+ | |||
+ | <tabber> | ||
+ | C#= | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | |||
+ | class Program { | ||
+ | public static String DoSomething(String value? = Null) { // optional nullable Parameter | ||
+ | if (value.HasValue) { | ||
+ | return value.Value; | ||
+ | } else { | ||
+ | return "BLARG"; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public static void Main(String[] Args) { | ||
+ | Console.WriteLine(DoSomething()) // Outputs "BLARG" | ||
+ | Console.WriteLine(DoSomething("YOZIT")) // Outputs "YOZIT" | ||
+ | Console.WriteLine(DoSomething(null)) // Outputs "BLARG" | ||
} | } | ||
} | } |
Revision as of 19:38, 17 December 2016
When a variable needs to be passed into a subroutine, this is done through the use of parameters. The subroutine can then use these parameters to execute its code. Parameters should be written inside the subroutine brackets, along with their variable type. In addition, multiple parameters should be separated by commas (",").
Contents
General Concept Example
1 namespace Project
2 {
3 class Program
4 {
5 static void Main(string[] args)
6 {
7 greeting("Geoff");
8 greeting("Bob");
9 }
10
11 static void greeting(string name)
12 {
13 Console.WriteLine("Hello, " + name);
14 }
15 }
16 }
17 //Output:
18 //Hello, Geoff
19 //Hello, Bob
Argument Scope
parameters passed to a function are passed as copies of their actual values and hence values sent and used as arguments by method are from a memory point of view different to the values actually passed. Because of this any changes made to arguments passed to a method have no affect on the value of the actual variable they're passed from, for example:
1 class Program {
2 public static void DoSomething(Object arg1) {
3 (int)arg1 += 1;
4 }
5
6 public static void Main(String[] Args) {
7 int test = 1;
8 Console.WriteLine(test); // Outputs 1;
9
10 DoSomething(test);
11 Console.WriteLine(test); // Outputs 1;
12
13 test += 1;
14 Console.WriteLine(test); // Outputs 2;
15 }
16 }
As the example above dictates Any from the moment the integer test1 is passed to the method DoSomething the argument used by the method is intrisically different to the variable passed to it. There are two way to circumvent this problem and attempt to save changes made by a method to a variable.
- One Method would be to declare the variable in a more globally accessible scope in relation to the two methods and edit them referencing directly to this variable declaration, for Example:
1 class Program {
2 public static void DoSomething() {
3 // int no longer passed as argument
4 testInt += 1;
5 }
6
7 public static void Main(String[] Args) {
8 testInt = 1;
9 Console.WriteLine(testInt); // Outputs 1;
10
11 DoSomething(); // testInt not passed as arg
12 Console.WriteLine(testInt); // Outputs 2;
13
14 testInt += 1;
15 Console.WriteLine(testInt); // Outputs 3;
16 }
17
18 public static int testInt; // int declared in same scope as two methods.
19 }
While this method has it's upside it's difficult to apply to an existing complex algorithm and doesn't actually involve any parameter passing, making it inefficient for the task it's trying to accomplish. On the other hand
- Another option would be to use the ref keyword in the parameter portion of the method, allowing the value being passed as an argument to be passed as a reference to the memory location of the actual variable instead of as a copy of the value stored at said memory location.
1 class Program {
2 public static void DoSomething(ref int intTestRef) {
3 intTestRef += 1;
4 }
5
6 public static void Main(String[] Args) {
7 int test = 1;
8 Console.WriteLine(test); // Outputs 1;
9
10 DoSomething(ref test); // passed as reference
11 Console.WriteLine(test); // Outputs 2;
12
13 test += 1;
14 Console.WriteLine(test); // Outputs 3;
15 }
16 }
This method is the preferred solution to keeping changes to passed parameters.
Unlimited Parameters
To pass as many arguments as you desire to a method, you can use the params keyword to set a method to accept as many parameters as given to it without throwing an exception, for example:
1 class Program {
2 public static String DoSomething(String seperator, params String[] args) {
3 return String.Join(seperator, args);
4 }
5
6 public static void Main(String[] Args) {
7 Console.WriteLine(DoSomething(" ", "BLARG", "BLARG2", "BLARG3")); // Outputs "BLARG BLARG2 BLARG3"
8 Console.WriteLine(DoSomething(" ", "BLARG")); // Outputs "BLARG"
9 Console.WriteLine(DoSomething("BLARG", " ", " ", " ")); // Outputs " BLARG BLARG "
10 }
11 }
Optional Parameters & nullable parameters
Parameters dont have to be mandatory, if required you can give a parameter a default value or mark it as nullable meaning it will be null unless something is passed to it. for example:
1 class Program {
2 public static String DoSomething(String value = "BLARG") { // optional Parameter value
3 return value;
4 }
5
6 public static void Main(String[] Args) {
7 Console.WriteLine(DoSomething()) // Outputs "BLARG"; Note No Parameter Passed
8 Console.WriteLine(DoSomething("YOZIT")) // Outputs "YOZIT"; Note Parameter Passed
9 Console.WriteLine(DoSomething(value : "BLARG")) // Outputs "BLARG"; Note Parameter Passed as named argument
10 }
11 }
this is an example of optional parameter passing, but such capabilty doesn't come without costs, for example optional parameters must be placed after mandatory parameters and must have an acceptable value, hence the following is invalid:
1 public static DoSomething(String value = "BLARG", int value2) {}
1 public static DoSomething(String value = 5) {}
To end things here I will explain nullable types, these are parameters which may or may not be used by a given method but do not have to have a set value, hence making them null. Nullable types come with a hefty HasValue attribute to let you now wether a given nullable is actually null or not, for Example:
1 class Program {
2 public static String DoSomething(String value? = Null) { // optional nullable Parameter
3 if (value.HasValue) {
4 return value.Value;
5 } else {
6 return "BLARG";
7 }
8 }
9
10 public static void Main(String[] Args) {
11 Console.WriteLine(DoSomething()) // Outputs "BLARG"
12 Console.WriteLine(DoSomething("YOZIT")) // Outputs "YOZIT"
13 Console.WriteLine(DoSomething(null)) // Outputs "BLARG"
14 }
15 }