• No results found

Passing parameters to functions

In document Basic c# (Page 30-40)

static void Main() {

string s;

s= "hell";

System.Console.WriteLine( "{0}", s);

} } Output hell

This program is exactly like the previous one, the only difference being that we have used {0} instead of writing only s. Here the {0} is replaced with the value of s, which is 'hell'. Thus, using the {0} is preferable as it understands a large number of data types and how to display their values.

Consolidating, our next example incorporates all the data types that we have learnt so far.

a.cs class zzz {

static void Main() {

string s;

int ii;

bool jj;

ii=10;

jj=false;

s="hell";

System.Console.WriteLine("{0} {1} {2}", ii, jj, s);

} } Output 10 False hell

Here the variable s is declared as a string. Then ii is declared as int and jj is declared as bool. In the next three statements we are initializing each of the variables. ii is initialized to 10, jj is initialized to false and s is initialized to hell. Now, with the help of a single WriteLine statement we are displaying the values of all the variables. {0} is replaced with 10, {1} is replaced with False and {2} is replaced with hell. This goes to prove that all the data types can be displayed together, in a single WriteLine statement.

Thus, C# allows all the data types to co-exist in harmony. Now only if the people of our country could do the same!

Passing parameters to functions

By now you are familiar with functions and how functions are called. The next program illustrates how parameters are passed to functions.

a.cs class zzz { static void Main() {

abc(10,false,"hell");

}

static void abc(int i, bool j, string s) {

System.Console.WriteLine("{0} {1} {2}", i,j,s);

} } Output 10 False hell

We have again used the System.Console.WriteLine function to display values of variables or merely display text onto the screen. To have it print something on to the screen, we had to give it the things that we wanted printed. These things are nothing but parameters. We don't pass things to functions; we pass parameters to functions. So far we never created our own functions with parameters.

In this program, we are calling the abc function with three things, with three parameters. The first is a number, the second is a logical value and the third is a string. So, we are passing the values 10, false and hell to the function abc(); These values must be stored somewhere, but where? When we create the function abc we have to state the names of three variables along with their respective data types. This is because the values that we pass will be stored in these variables. Hence we have the variables i, j and s.

These are then displayed using WriteLine. Therefore, it will output 10, False and hell. This is how parameters are passed to functions in C#. Remember you decide what names to give to variables.

Parameters passed to functions are also variables.

a.cs

class zzz { static void Main() {

abc(10,false);

}

static void abc(int i, bool j, string s) {

System.Console.WriteLine("{0} {1} {2}", i,j,s);

} }

Compiler Error

a.cs(4,1):error CS1501: No overload for method 'abc' takes '2' arguments

On compiling this program you will encounter the above error. Here we are calling abc with only two parameters, 10 and false. Whereas the function abc is actually created with three parameters. We are passing an erroneous number of parameters, hence the error. Lesson? One must pass the same number of parameters that the function has been created to accept. A mismatch between the number of parameters being passed and those being accepted will definitely assure you of an error. Thus as before, C# does a large number of error checks on your code. For, if it allowed the above function call to go ahead, what would the value of the third parameter s be?

Now change the order of the values that are being passed. Your abc function should look like this- abc("hell",10, false);

a.cs class zzz {

static void Main()

{

abc("hell",10,false);

}

static void abc(int i, bool j, string s) {

System.Console.WriteLine("{0} {1} {2}", i,j,s);

} }

Compiler Error

a.cs( 5,1): error cs1502: The best overloaded method match for 'zzz.abc(int, bool, string)' has some invalid arguments

a.cs( 5,5 ): error cs1503: Argument '1': cannot convert from 'string' to 'int' a.cs(5,12): error cs1503: Argument '2': cannot convert from 'int' to 'bool' a.cs(5,15): error cs1503: Argument '3': cannot convert from 'bool' to 'string'

On executing this program you will be faced with the above errors. These errors have resulted due to a data type mismatch. It is somewhat like putting a round pole in a square peg! How is it going to fit?

While calling the function abc() the first parameter that we are passing is the word "hell". But the function abc() has been created to accept the first parameter as an int. Remember we told you, not so long ago, that C# distinguishes between data types. Thus you can't store a string in a variable of type int.

Similarly, the value 10 cannot be stored as a bool and false cannot be stored as a string. Therefore, not only should the number of parameters being passed and accepted be the same but also their data types must match.

Like oil and water do not mix, in the same way you cannot give C# an int when it wants a string. As said earlier, some languages are more forgiving then C# due to which the programmer makes more mistakes in them.

a.cs class zzz {

static void Main() {

abc();

} }

class yyy {

static void abc() {

System.Console.WriteLine("abc");

} }

Compilation Error

a.cs(5,1): error CS0103: The name 'abc' does not exist in the class or namespace 'zzz' Seems like we are hooked on to errors!

In this program we have created another class called yyy. We can have as many classes in one .cs file as we like. This program now has two classes, zzz and yyy. The class zzz has a function called Main. Main denotes the starting point of our code and as such is the first function to be called. The class yyy contains a function called abc. Here we are calling the function abc by saying abc(); in class zzz. But class zzz does not have any function by the name abc. Merely giving abc(); encourages C# to assume that abc() exists within the class zzz. But our abc function is contained in yyy. Hence we get an error as we are trying to call a function that exists in another class.

But we are adamant! We want to use the abc function that yyy has. It's human tendency to want things that others have! So, in the next program we are calling the function abc in the class yyy by writing yyy.abc();

a.cs class zzz {

static void Main() {

yyy.abc();

} }

class yyy {

static void abc() {

System.Console.WriteLine("abc");

} }

Compilation Error

a.cs(5,1): error cs0122: 'yyy.abc() is inaccessible due to its protection level.

When we say yyy.abc(); why the dot? yyy is the name of the class and abc() is the name of the function . Each of these names can be as large as you want, so to separate them a dot is used. Thus when you want to access a function that belongs to another class you can do so by specifying the class name and function name separated by a dot. The dot is like the semicolon. The designers of the language wanted some character as a separator between class name and function name, they chose the dot, they could have also chosen the semicolon again.

You will now realize why we say Console.WriteLine. Obviously, it means that Console is a class and within the class Console there is a function called WriteLine.

But to your dismay, on executing this program you still get an error. Well, few people get what they want, however fewer still want what they get! You may want a particular thing but you will not get it unless the other party gives you the permission to take it, use it or share it. Your only other option is to put up a fight!

We get an error here because we haven't used the word public. The whole idea behind C# is its usability on the net. And the only way you can use it on the net is by having security precautions. So in C# the default rule is - you can't use anything unless explicitly granted permission. Next question. How do you grant the necessary permission?

Being its non-violent self, C# grants permission by using the word public. When we say public, we mean the world at large. So by starting with the word public we are saying that the whole world is now allowed to use this function as we are explicitly granting you rights. If you don't use the word public it will give you an access error.

To rectify the error, add the word public just as we have done below.

a.cs class zzz {

static void Main() {

yyy.abc();

}

}

class yyy {

public static void abc() {

System.Console.WriteLine("abc");

} }

Output abc

Finally, we have the correct code! See, one of life's greatest ironies is the fact that when you finally master a tough job, you make it look easy!! By using the word public in front of the function abc, we can now call it from zzz by specifying yyy.abc(); Now that the function is called, WriteLine displays 'abc'.

Our next example will enhance your understanding further.

a.cs class zzz {

static void Main() {

yyy.abc();

abc();

zzz.abc();

}

public static void abc() {

System.Console.WriteLine("abc in zzz");

} }

class yyy {

public static void abc() {

System.Console.WriteLine("abc");

} } Output abc abc in zzz abc in zzz

Now we go a step further. In the above program we have two abc functions, one in class zzz and one in class yyy.

If you want to call the one in yyy then you say yyy.abc(); but if you want to call the one in zzz then you say zzz.abc() or abc(). The function abc(), by itself, will ask which class is it? Since abc() is in zzz itself, C# assumes it to zzz.abc(); By implication, if the function exists within the same class, it is optional to preface the function with the name of the class. When you execute this program, yyy.abc() will call the abc function in class yyy and

WriteLine will display 'abc'. Thereafter, both abc() and zzz.abc() will call the abc function in class zzz. And in each case WriteLine will display 'abc in zzz'. Thus if you do not preface the function name with the name of the class, C# will add the name of the class in which you are calling the function. In our case it is zzz.

2

Namespaces

Normally, students have an implicit trust in their teachers. For they know that if the blind lead the blind, both shall fall into the ditch. However, our philosophy is that a good teacher has to be an even better liar!!

In accordance with this belief, initially we told you that WriteLine is the name of a function. Then we told you that the name is not WriteLine, it is System.Console.WriteLine. But even that's not true.

Now comes the moment of truth.

Console is actually the name of a class. Yes, trust us! There is no crying wolf here. The class Console has a function called WriteLine. Hence the name now becomes Console.WriteLine. However, that leaves out the word System. Now what does System mean?

Well, a number of functions like WriteLine are available in C#. Some functions will let you print, some will enable writing of data to disk and others will let you create graphics. The problem that we are posed with is - how does one remember which function satisfies what purpose?

Wouldn't it make sense if we logically grouped similar functions together? So, Microsoft thought that all functions that can write to the screen could be made part of one class. All functions that let you work with pictures could be part of another class. But even then, you will have too many functions in one class. So they thought of having a single higher logical group. Such that all the functions that have anything to do with the screen, i.e. whether you are drawing pictures or writing text, be grouped once again into a higher body. Thus all classes that deal with interacting with a database could go into a group called Data.

The second problem that we are posed with is that of name clashes. What do we mean by that? Now, nothing can stop me from creating my own class called Console and include a function called WriteLine in it. But how will C# know which Console am I referring to? The one that we created ourselves, or the one that Microsoft has already created. In order to resolve these problems Microsoft decided to take classes and put them into namespaces. What is a namespace? It is simply a word. Thus we can logically group everything as per namespaces.

From the above explanation you would have by now guessed that System is nothing but a namespace.

The following programs will help make this concept crystal clear.

a.cs class zzz {

static void Main() {

yyy.abc();

abc();

zzz.abc();

}

public static void abc() {

System.Console.WriteLine("abc in zzz ");

} }

namespace vijay {

class yyy {

public static void abc() {

System.Console.WriteLine("abc");

} } }

Compiler Error

a.cs(5,1): error CS0246: The type or namespace name 'yyy' could not be found (are you missing a using directive or an assembly reference?)

In the above program, the only change that we have made is that we have now included the class yyy in a namespace called vijay. On doing so you will realize that the same program that worked earlier doesn't work anymore. This is because yyy is put in a namespace vijay.

A namespace is nothing but a word with an open and close brace. The entire class is enclosed within the namespace. If you want to access a function belonging to class yyy from another class then the only way to do so is by saying vijay.yyy.abc(); Thus you specify the namespace first, then the name of the class followed by the name of the function, each of them separated by dots. Thus like Urdu, we read anything from the right and not the left. We start with the name of a function, then the name of the class and whatever is left is the namespace.

Here zzz has not been given a namespace. If you don't specify a namespace then by default the class is included in a global namespace. Now change yyy.abc(); to vijay.yyy.abc() and watch the error disappear.

a.cs class zzz {

static void Main() {

vijay.yyy.abc();

abc();

zzz.abc();

}

public static void abc() {

System.Console.WriteLine("abc in zzz ");

} }

namespace vijay {

class yyy {

public static void abc() {

System.Console.WriteLine("abc");

} } } Output abc abc in zzz abc in zzz

We bet your faces are now beaming! Seems like the secret of happiness is not in doing what one likes to do but in liking what one has to do. We had to get rid of the error which we have succeeded in doing.

The error has disappeared; the program executes as advertised and it generates the same output as it did previously.

Thus all the classes and functions created by Vijay can be included in a namespace called vijay. If Sonal creates a namespace by her name then she can include all the functions and classes created by her in the namespace sonal. Thus there will be no name clashes at all. These namespaces that are created by us are called user-defined namespaces whereas System is a pre-defined namespace. Thus System is a namespace in which a class called Console was created, which contained a function called WriteLine.

Thus the namespace concept allows us to create logical groups. So all xml related classes can be in a namespace called xml, web can be in a web namespace and so on and so forth.

But the only problem now is that when you start writing code you have to specify the namespace first, then the class name followed by the function name. Well, everything is available but for a price! Our consolation is that it is a very small price to pay.

a.cs

namespace mukhi {

class zzz {

static void Main() {

vijay.yyy.abc();

abc();

zzz.abc();

mukhi.zzz.abc();

}

public static void abc() {

System.Console.WriteLine("abc in zzz ");

} } }

namespace vijay {

class yyy {

public static void abc()

{

System.Console.WriteLine("abc");

} } } Output abc abc in zzz abc in zzz abc in zzz

In the above program, we have two classes zzz and yyy. The class zzz is included in a namespace called mukhi and the class yyy is included in a namespace called vijay.

So when we say abc(); in Main, Main is in zzz, so you are actually writing mukhi.zzz.abc(); This is because C# will automatically expand it since the function abc is available within the same class. Hence it is at your discretion as to how you want to write it. You can say abc(), zzz.abc() or mukhi.zzz.abc();

finally they all expand to namespace.classname.function name. C# adds the name of the namespace and the name of the class even if you do not specifically write it. The concept of namespaces is not very difficult to understand. It allows for a hierarchical grouping of classes. It tells us which classes are logically grouped. It also avoids classes from having the same name.

a.cs class zzz {

static void Main() {

Console.WriteLine("abc in zzz ");

} }

Compiler Error

a.cs(5,1): error CS0246: The type or namespace name 'Console' could not be found (are you missing a using directive or an assembly reference?)

If we do not enclose our class in a namespace, it becomes part and parcel of the global namespace ‘ ‘.

This namespace does not contain a class called Console. We had mentioned earlier that the class Console is contained in the namespace System. We do not want to preface the Console class with the namespace System each and every time. The only reason being that our fingers will wear out typing the word System over and over again. So C# lets us use a shorthand by means of which we avoid the pain of having to keep on writing the name of a namespace over and over again.

a.cs

using System;

class zzz {

static void Main() {

Console.WriteLine("abc in zzz ");

} } Output abc in zzz

The secret here is not in doing great things, but doing a small thing in a great way. We get no error simply by employing the word using which is part of the C# language. All that using does is whenever it

sees only the name of a class, it goes and adds (in this case) the word System. Thus we do not have to write the word System over and over again. This works the way shorthand does.

a.cs

using System;

class zzz {

static void Main() {

yyy.abc();

} }

namespace vijay {

class yyy {

public static void abc() {

Console.WriteLine("abc");

} } }

Compiler Error

a.cs(6,1): error CS0246: The type or namespace name 'yyy' could not be found (are you missing a using directive or an assembly reference?)

Now we get an error for yyy and not for Console as the yyy class belongs to the vijay namespace and

Now we get an error for yyy and not for Console as the yyy class belongs to the vijay namespace and

In document Basic c# (Page 30-40)