Friday, April 12, 2019

C# Interfaces and Structures

Constructors Revisited

A constructor is used to initialize the instance of a class as explained earlier.

a.cs
public class zzz
{
public static void Main()
{
System.Console.WriteLine("in main");
bb a = new bb();
bb b = new bb(10);
}
}
public class aa
{
public aa()
{
System.Console.WriteLine("in const aa");
}
public aa(int i)
{
System.Console.WriteLine("in const aa" + i);
}
}
public class bb : aa
{
public bb()
{
System.Console.WriteLine("in const bb");
}
public bb(int i)
{
System.Console.WriteLine("in const bb" + i);
}
}

Output
in main
in const aa
in const bb
in const aa
in const bb10

Class aa is the base class. It consists of two constructors. One that takes no parameters and the other that takes an int as a parameter. Class bb is derived from class aa, i.e. aa is the base class, bb the derived class. When we create an object like bb, the compiler does not execute the code for the constructor but instead asks the constructor which constructor of the base class to execute first. As we haven't stated this, by default, the constructor with no parameters get executed. Remember  it is the base class constructor which gets executed first and the derived class constructor specifies which base class constructor to call first. In the second case, even though we are calling the constructor with a parameter, the constructor with no parameters in the base class gets called and not the one with one int as a parameter.




a.cs
public class zzz
{
public static void Main()
{
System.Console.WriteLine("in main");
bb a = new bb();
bb b = new bb(10);
}
}
public class aa
{
public aa()
{
System.Console.WriteLine("in const aa");
}
public aa(int i)
{
System.Console.WriteLine("in const aa" + i);
}
}
public class bb : aa
{
public bb() : base()
{
System.Console.WriteLine("in const bb");
}
public bb(int i) : base(i)
{
System.Console.WriteLine("in const bb" + i);
}
}

Output
in main
in const aa
in const bb
in const aa10
in const bb10

If we do not specify which constructor of the base class to call, C# by default calls the constructor with no parameters. Which means that C# rewrites our code . When we write bb(), it gets rewritten as bb() : base(). Base is a reserved word. It means call the constructor of the base class with no parameters. For the second constructor, bb(int i), the line gets rewritten to bb(int i) : base(). We now want to call the constructor with one int and hence we write bb(int i) : base(i). That is why the constructor with one int gets called. We have the option to decide which constructor of the base class we would like to call.

a.cs
public class zzz
{
public static void Main()
{
System.Console.WriteLine("in main");
bb a = new bb();
}
}
public class aa
{
public aa()
{
System.Console.WriteLine("in const aa");
}
public aa(int i)
{
System.Console.WriteLine("in const aa" + i);
}
}
public class bb : aa
{
public bb() : this(20)
{
System.Console.WriteLine("in const bb");
}
public bb(int i) : base(i)
{
System.Console.WriteLine("in const bb" + i); } }
Output
in main
in const aa20
in const bb20
in const bb

A constructor gets called at the time of creation of the object. At the line, new bb(), the compiler asks the constructor of bb as to which constructor of the base class aa to call. Here he was told that the answer lies with this(20). this, like base, is a reserved word. It means call a constructor of the same class and not the base class. Therefore the compiler now asks the one constructor of the derived class bb which constructor of the base class to call. bb(int i) : base(i) tells the compiler to execute the one int constructor of aa. This is the first constructor that gets called. Then the one int constructor of bb gets called and finally the one who started it all, the no parameter constructor of bb. Thus, two derived class constructors get called instead of one.

a.cs
public class zzz
{
public static void Main()
{
System.Console.WriteLine("in main");
aa a = new aa();
}
}
public class aa
{
private aa()
{
}
}

Compiler Error
a.cs(6,8): error CS0122: 'aa.aa()' is inaccessible due to its protection level

When you create a constructor which is private, you cannot create an object that looks like aa. Thus aa should only contain static members.

a.cs
public class zzz
{
public static void Main()
{
}
}
public class aa
{
private aa()
{
}
}
public class bb : aa
{
}

Compiler Error
a.cs(13,14): error CS0122: 'aa.aa()' is inaccessible due to its protection level

Nor can any class derive from aa. Thus no one can instantiate an object that looks like aa or derive from it as the constructor has been made private.

a.cs
public class zzz
{
public static void Main()
{
System.Console.WriteLine(aa.i);
}
}
public class aa
{
private aa()
{
}
static public int i = 20;
}

Output
20

You can however use all the static variables in aa

a.cs
public class zzz
{
public static void Main()
{
}
}
class yyy
{
public yyy()
{
}
}
class xxx : yyy
{
public int i;
xxx() : base( this.i)
{
}
}

Compiler Error
a.cs(16,15): error CS0027: Keyword this is not available in the current context

Base is called a constructor initializer. When base gets called, the instance or the object has not yet been created. Ergo, this is not available here as this refers to the current object. In the constructor, however, this can be freely used.

The values of variables in a class are initialized to their default values as per their  data types before the constructor gets called.  Thus, in the constructor they have their default values as shown below.

a.cs
public class zzz
{
public static void Main()
{
yyy a = new yyy();
}
}
class yyy
{
public int i;
public bool j;
public yyy()
{
System.Console.WriteLine(i+" " + j);
}
}

Output
0 False

Here as before, the first line of code in the constructor gets executed.

a.cs
public class zzz
{
public static void Main()
{
xxx a = new xxx();
}
}
class yyy
{
public int i = 10;
public yyy(int j)
{
System.Console.WriteLine(i);
i = j;
}
}
class xxx : yyy
{
public xxx() : base(100)
{
System.Console.WriteLine(base.i);
}
}

Output
10
100

Calling the base class constructor is like inserting all the code of the one int constructor i.e. yyy(int j), in the constructor of class xxx. We are also allowed to access members of the base class after the constructor gets called. Also, first the variable i gets initialized to 10 or the default value of int. Then we change it to 100 and in the constructor of xxx, we will see a value of 100.

a.cs
public class zzz
{
public static void Main()
{
xxx a = new xxx();
}
}
class yyy
{
public yyy()
{
abc();
}
public virtual void abc()
{
}
}
class xxx : yyy
{
public int x = 10;
public xxx()
{
System.Console.WriteLine(x);
x = 100;
System.Console.WriteLine(x);
}
public override void abc()
{
System.Console.WriteLine(x);
}
}

Output
10
10
100

We have already confessed a million times in the past that we have copied ideas from anyone and everyone, specially from the documentation. In this specific case, we wanted to demonstrate that first the variables are initialized. Thus in class xxx, the int x is initialized to 10. Then the base class constructor of yyy gets called. The value of x in class yyy should be 10. But what guarantee can we give you as we are not able to print the value of x in an object of a class derived from the base class. Very simple. We call a virtual function abc from class yyy and override it in class xxx. The abc of class xxx prints the value of x as they belong to the same class and the output is 10. Viola and thank you Mr. Documentation for the above thought and many more such ideas. Once all code in the yyy constructor is executed, the first line in xxx constructor will get executed which will print the value of x as 10. x is then initialized to 100, hence we see 100 as the new value of x, displayed on the screen.

a.cs
public class zzz
{
static zzz()
{
System.Console.WriteLine("zzz");
}
public static void Main()
{
System.Console.WriteLine("main");
new aa();
}
}
public class aa
{
public aa()
{
System.Console.WriteLine("aa");
}
static aa()
{
System.Console.WriteLine("static aa");
}
}

Output
zzz
main
static aa
aa

and if we comment new aa() then the resulting output reads as follows.

Output
zzz
main

A static constructor gets called before any other constructors.

a.cs
public class zzz
{
static zzz()
{
System.Console.WriteLine("zzz");
}
public static void Main()
{
System.Console.WriteLine("main");
aa.a();
}
}
public class aa
{
public aa()
{
System.Console.WriteLine("aa");
}
public static void a()
{
}
static aa()
{
System.Console.WriteLine("static aa");
}
}

Output
zzz
main
static aa

If you try to access any static member of a class or whenever you instantiate an object, the static constructor gets called. A constructor is not inherited by the derived class.

A class is loaded in memory before any instance of the class is created or its static members accessed. A class can only be loaded once and that too before its derived class is loaded. The static constructor is called at the time of loading the class. Like other constructors, a static constructor cannot be explicitly called.

a.cs
public class zzz
{
public static void Main()
{
xxx.pqr();
yyy.abc();
}
}
class yyy {
static yyy()
{
System.Console.WriteLine("static yyy");
}
public static void abc()
{
System.Console.WriteLine("abc yyy");
}
}
class xxx {
static xxx()
{
System.Console.WriteLine("static xxx");
}
public static void pqr()
{
System.Console.WriteLine("pqr xxx");
}
}

Output
static xxx
pqr xxx
static yyy
abc yyy
Do not believe the above results as if you run them on your machine, your mileage may wary. This is because C# does mandate the order of loading of classes and thus the order of execution of the static constructors. On your machine if the yyy constructor gets executed first, do not panic. Blame it on your destiny.

a.cs
public class zzz
{
public static void Main()
{
yyy.abc();
xxx.pqr();
}
}
class xxx
{
static xxx()
{
System.Console.WriteLine("static xxx");
}
public static void pqr()
{
System.Console.WriteLine("pqr xxx");
}
}
class yyy : xxx
{
static yyy()
{
System.Console.WriteLine("static yyy");
}
public static void abc()
{
System.Console.WriteLine("abc yyy");
}
}


Output
static yyy
abc yyy
static xxx
pqr xxx

We have made only one small change in the above program. We have derived the class yyy from xxx. Since the functions in each class are marked static, the program behaves in the same manner as before.The above order of calls remains the same. If an object of the type is created, then the output will change. The reason being that before the object of type yyy is created, xxx must be loaded. Hence the constructors will be called first.

a.cs
public class zzz
{
public static int x = yyy.y + 2;
static zzz()
{
System.Console.WriteLine("static zzz " + zzz.x + " " + yyy.y);
x = 500;
yyy.y = 600;
System.Console.WriteLine("static zzz " + zzz.x + " " + yyy.y);
}
public static void Main()
{
System.Console.WriteLine("main "+ zzz.x + " " + yyy.y);
}
}
class yyy
{
static yyy()
{
System.Console.WriteLine("static yyy " + zzz.x + " " + yyy.y);
y = 10;
zzz.x = 200;
System.Console.WriteLine("static yyy " + zzz.x + " " + yyy.y);
}
public static int y = zzz.x + 3; }
Output
static yyy 0 3
static yyy 200 10
static zzz 12 10
static zzz 500 600
main 500 600

Difficult code to understand and follow. C# first tries to load class zzz in memory as it contains the function Main. Unfortunately it realizes that it has to first initialize the variable x before calling the static constructor of zzz. It first initializes x to 0. Now note that this initialization of x to zero is extremely significant for our understanding. To get the new value of x, C# now needs the value of the variable y from the class yyy. Before it can call the static constructor of yyy it must initialize the variable y. It makes sure that y's value is first set to zero. It then computes the value of zzz.x which is zero as stated above. We are yet left hanging in class zzz at the line x = . As zzz.x is zero, the value of y is 0 + 3 i.e. 3. This completes the initialization of all the variables in the class. All this happens first. Thus the static constructor of class yyy shows the value of the variable x as 0 and that of variable y as 3.

But hold on, the fun is yet to begin.  In the static constructor, we now initialize y to 10 and the x of zzz to 200. The next WriteLine confirms that our initializations actually were carried out. Then we go back to class zzz. Here we come back to the initialization of the static variable x. As yyy.y is now 10  since we changed it in the static constructor of yyy, the value of x is 10 + 2 i.e. 12. This overrides the value of x which we changed to 200 in the static constructor yyy. Now C# calls the static constructor of zzz as it has finished all the variable initializations. Thus the first WriteLine displays 12 and 10. We are now changing both x and y and they display the same values in the constructor and in Main.

a.cs
public class zzz
{
public static int x = yyy.y + 2;
static zzz()
{
System.Console.WriteLine("static zzz " + zzz.x + " " + yyy.y);
x = 500;
yyy.y = 600;
System.Console.WriteLine("static zzz " + zzz.x + " " + yyy.y);
}
}
class yyy
{
static yyy()
{
System.Console.WriteLine("static yyy " + zzz.x + " " + yyy.y);
y = 10;
zzz.x = 200;
System.Console.WriteLine("static yyy " + zzz.x + " " + yyy.y);
}
public static int y = zzz.x + 3;
public static void Main()
{
System.Console.WriteLine("main "+ zzz.x + " " + yyy.y);
}
}

Output
static zzz 2 0
static zzz 500 600
static yyy 500 503
static yyy 200 10
main 200 10

The above program adds a small twist. It bowls what in cricket parlance is called a googly. We simply bring Main from the class zzz to the class yyy. Now C# as usual first starts at the class containing Main which now happens to be yyy and not zzz. Here it has to first initialize all the variables in class yyy. We have only one. It starts by setting y to zero and runs to the class zzz to fetch the value of x. x now become 0 + 2 i.e. 2. Then in the static constructor, we are displaying the relevant values of x and y. In the static constructor of class zzz, we are changing x and y to 500 and 600 respectively and displaying the values. When we move back to class yyy, however, y gets  a new value of 503 as x is 500. y loses its value of 600 that was initialized in zzz, hence you see 500 and 503. The rest remains the same as explained in the earlier example.

Interfaces

An interface is simply a collection of function prototypes. Like we derive a class from another, so also we could derive from an interface.

a.cs
class zzz
{
public static void Main()
{
}
}
interface ddd
{
void a1();
void a2();
}
class yyy : ddd
{
}

Compiler Error
a.cs(12,7): error CS0535: 'yyy' does not implement interface member 'ddd.a1()'
a.cs(12,7): error CS0535: 'yyy' does not implement interface member 'ddd.a2()'

We have just created an interface called ddd by using a new keyword interface in place of a class. Our interface ddd has two function prototypes, a1 and a2. We can derive from our interface ddd like we derived from a class. The difference is that an interface has no code, only function prototypes. Whenever we derive from an interface, we have to implement the code or body of the function. A class gives you lots of free code, an interface does not. The error is generated as we have not given the code for a1 and a2 in yyy

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
a.a1();
ddd d = new yyy();
d.a2();
}
}
interface ddd
{
void a1();
void a2();
}
class yyy : ddd
{
public void a1()
{
System.Console.WriteLine("yyy a1");
}
public void a2() {
System.Console.WriteLine("yyy a2");
}
}

Output
yyy a1
yyy a2

We get no errors because we have now implemented the code of a1 and a2. Looks wise we do no know whether ddd is a class or an interface as the syntax at the time of derivation is the same. d is an object that looks like an interface which is syntactically correct. d can be equated to a yyy as a yyy is a yyy + a ddd. We can, by only using d, call members of a ddd.
a.cs
class zzz
{
public static void Main()
{
aaa a ;
a = new aaa();
}
}
interface aaa
{
}

Compiler Error
a.cs(6,5): error CS0144: Cannot create an instance of the abstract class or interface 'aaa'

Even though an interface aaa is empty, we cannot write the keyword new in front of it. An interface contains no code and thus cannot be instantiated. However we are allowed to declare objects that look like an interface. Therefore, in this case, the line aaa a, does not flag an error.

a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
void a1()
{
}
}

Compiler Error
a.cs(9,6): error CS0531: 'aaa.a1()': interface members cannot have a definition
Reiterating, an interface can only contain function prototypes, no code at all. The functions cannot have a definition.

a.cs
class zzz
{
public static void Main()
{
}
}
class xxx
{
}
class vvv
{
}
class yyy : xxx,vvv
{
}

Compiler Error
a.cs(13,17): error CS0527: 'vvv' : type in interface list is not an interface

C# does not support multiple inheritance. We can derive from a single class only at one point in time.

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
ddd d = new yyy();
d.a1(); d.a2();
a.a1();
a.a2();
}
}
interface ddd
{
void a1();
void a2();
}
class yyy : ddd
{
public void ddd.a1()
{
System.Console.WriteLine("a1");
}
public void a2()
{
System.Console.WriteLine("a2");
}
}

Compiler Error
a.cs(19,13): error CS0106: The modifier 'public' is not valid for this item

You are not allowed to use the modifier public for a function which has qualified its  name with that of the interface.

a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
public void a1();
}

Compiler Error
a.cs(9,13): error CS0106: The modifier 'public' is not valid for this item
Interface members are public by default. The access modifiers are not allowed here. All the other access modifier rules remain the same as that from classes. The rules in classes stated that the base class must be at least as accessible as the derived class. Replace the word class with interface and you will not be sorry.

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
ddd d = new yyy();
d.a1(); d.a2();
a.a1();
a.a2();
}
}
interface ddd
{
void a1();
void a2();
}
class yyy : ddd
{
void ddd.a1()
{
System.Console.WriteLine("a1");
}
public void a2()
{
System.Console.WriteLine("a2");
}
}

Compiler Error
a.cs(8,1): error CS0117: 'yyy' does not contain a definition for 'a1'


The reason we get an error is because we created the function a1 in yyy as ddd.a1 and not a1. By doing this, we were telling C# that only objects that look like ddd are allowed access to a1. Even an object that looks like yyy is not allowed to access a1. Comment out line number 8 i.e. a.a1 and all works fine as follows

Output
a1
a2
a2

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
ddd d = new yyy();
eee e = new yyy();
a.a1(); a.a2();
d.a1();
e.a2();
}
}
interface ddd
{
void a1();
}
interface eee
{
void a2();
}
class yyy : ddd , eee
{
public void a1()
{
System.Console.WriteLine("a1");
}
public void a2()
{
System.Console.WriteLine("a2");
}
}

Output
a1
a2
a1
a2

Here we are doing something that just cannot be done with classes. We are deriving from two interfaces ddd and eee at the same time. Each has one function prototype a1 and a2 respectively. Using a which looks like yyy we can call both a1 and a2 but with d that looks like ddd we can only call a1. Similarly, with e only a2 can be called.

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
ddd d = new yyy();
eee e = new yyy();
a.a1();
d.a1();
e.a1();
}
}
interface ddd
{
void a1();
}
interface eee
{
void a1();
}
class yyy : ddd , eee
{
public void a1()
{
System.Console.WriteLine("a1");
}
}

Output
a1
a1
a1

The two interfaces share the same function name a1. We do not get an error but yet things do not seem right. Both  d and e call the same a1 and there is only one implementation of the function a1. We would like to have two a1's but we cannot have the same function defined twice in a class.

a.cs
class zzz
{
public static void Main()
{
ddd d = new yyy();
eee e = new yyy();
d.a1();
e.a1();
}
}
interface ddd
{
void a1();
}
interface eee
{
void a1();
}
class yyy : ddd , eee
{
void ddd.a1()
{
System.Console.WriteLine("ddd a1");
}
void eee.a1()
{
System.Console.WriteLine("eee a1");
}
}

Output
ddd a1
eee a1

We did what we had explained earlier. We prefaced  the name of the function with the name of the interface. Then we removed the modifier public and the object a which looked like yyy. Now each interface has its own copy of a1 to be called. ddd.a1 is called the explicit interface member name.

a.cs
class zzz
{
public static void Main()
{
yyy a = new yyy();
a.a1();
}
}
interface ddd
{
void a1();
}
interface eee
{
void a1();
}
class yyy : ddd , eee
{
void ddd.a1()
{
System.Console.WriteLine("ddd a1");
}
void eee.a1()
{
System.Console.WriteLine("eee a1");
}
}

Compiler Error
a.cs(6,1): error CS0117: 'yyy' does not contain a definition for 'a1'

The reason we removed a was that once we have an explicit interface member, we cannot access it through the class, it is done only through the interface. This make a lot of sense as there are two functions of the same name, and C# does not know which one it should call. By prefacing the functions  with the names of the interface, we are making them part of the interface and not the class. In a sense they are private to the class. As there is no function by the name of a1 in class yyy, we see the above error.

a.cs
class zzz
{
public static void Main()
{
}
}
interface ddd
{
void a1();
}
interface eee
{
void a1();
}
class yyy : ddd
{
void ddd.a1()
{
}
void eee.a1()
{
}
}

Compiler Error
a.cs(21,6): error CS0540: 'yyy.eee.a1()': containing class does not implement interface 'eee'

We get an error as class yyy is derived only from interface ddd. Thus we cannot use eee.a1() as interface eee is not a base interface for class yyy.

a.cs
class zzz
{
public static void Main()
{
}
}
interface ddd
{
void a1();
}
class yyy : ddd
{
void ddd.a1()
{
}
}
class xxx : yyy
{
void ddd.a1()
{
}
}

Compiler Error
a.cs(19,6): error CS0540: 'xxx.ddd.a1()': containing class does not implement interface 'ddd'
The key concept earlier was that we could only use the name of an interface explicitly if it was categorically stated as a base class. Anything indirect would not do. Here class yyy is derived from interface ddd and thus we can use the form ddd.a1. However even though class xxx is derived from class yyy and thus also from interface ddd, we are not allowed to write ddd.a1 as interface ddd is not explicitly stated in the derivation list of class xxx.

An interface defines a contract and can only contain four entities viz  methods, properties, events and indexers. An interface thus cannot contain constants, fields, operators, constructors, destructors, static constructors, or types. Also an interface cannot contain static members of any kind. The modifiers abstract, public, protected, internal, private, virtual, override are disallowed as they make no sense in this context.

a.cs
class zzz
{
public static void Main()
{
}
}
public delegate void d1();
public interface aaa
{
void a1(string s);
int a2
{
get; set ;
}
event d1 ddd;
string this[int i]
{
get; set;
 } }

The above example demonstrates the four entities an interface can contain. Anything else will flag an error.
a.cs
class zzz
{
public static void Main()
{
ccc c = new ccc();
aaa a = c;
bbb b = c;
c.a1();c.a2();
a.a1();
b.a1();b.a2();
}
}
interface aaa
{
void a1();
}
interface bbb : aaa
{
void a2();
}
class ccc : bbb
{
public void a1()
{
System.Console.WriteLine("a1");
}
public void a2()
{
System.Console.WriteLine("a2");
}
}

Output
a1
a2
a1
a1
a2

An interface can also, like a class, inherit from one or more interfaces. In this case bbb as an interface, can inherit from aaa. The class ccc  inherits from interface bbb and and thus interface aaa has to implement functions a1 and a2. The object c not only looks like a ccc but also looks like an aaa and bbb. Thus equating them does not give an error. The reverse, however, is not true. It will obviously flag an error. However a can only access functions from the interface it belongs to, in this case a1 and b can access a1 and a2. b cannot access members from class ccc even though a, b, and c have the same values. Whenever an interface derives from another it is called an explicit base interface. Like classes, circular definitions are not permitted. In fact nowhere in the C# programming language are we permitted to have circular definitions.

An interface also creates a new type and as in classes, methods must have their own unique signatures. Properties and methods cannot have similar names.

a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
void a1();
}
interface bbb : aaa
{
void a1();
}

Compiler Warning
a.cs(13,6): warning CS0108: The keyword new is required on 'bbb.a1()' because it hides inherited member 'aaa.a1()'

Like classes if interfaces derive from each other, there is a possibility that they may contain the same function signatures. Thus we get a warning which can be removed by adding the keyword new as follows.

interface bbb : aaa
{
new void a1();
}

The point to be stressed here is that the keyword new really does not do much, other than remove the warning. This is because the implementation of the interface is done in the class. There, we will have only one implementation of function a1 and not two, one for aaa and the other for bbb. At one level, from the point of view of the class which derives from interface bbb, it will see only one function in it, not two. All that we are doing is hiding the base interface member.

a.cs
class zzz
{
public static void Main()
{
}
void abc(ccc c)
{
c.aa(1);
((bbb)c).aa(1);
((aaa)c).aa(1);
c.aa = 2;
((aaa)c).aa = 3;
((bbb)c).aa = 3;
}
}
interface aaa
{
int aa
{
get; set;
}
}
interface bbb
{
void aa(int i);
}
interface ccc : aaa , bbb
{
}

Compiler Error
a.cs(8,1): error CS0229: Ambiguity between 'aaa.aa' and 'bbb.aa(int)'
a.cs(10,10): error CS0118: 'aaa.aa' denotes a 'property' where a 'method' was expected
a.cs(11,1): error CS0229: Ambiguity between 'aaa.aa' and 'bbb.aa(int)'
a.cs(13,10): error CS0654: Method 'bbb.aa(int)' referenced without parentheses

Interface aaa has only one member, a property called aa, whereas interface bbb has one function called aa. The interface ccc does not give us an error in spite of the fact that we have a property and a function with the same name. In the function abc, we are passing c, an object that looks like ccc. The line c.aa(1) gives us an error as we have a property and a function called aa. C# gets confused whether it is the property or the function we are referring to. In our humble opinion, we could only be referring to the function as per the syntax, but you don't argue with a compiler.

In the second case c.aa = 2 also flags an error due to the name confusion. In this case also, we could only be referring to a property. The only way out is to cast. The second cast in each case gives an error as the syntax for calling a function and property is different. Normally, to cast, we need to give two sets of brackets.

A cast incurs no run time costs i.e.,  it does not slow down the program. All that a cast does in the above case is lowers the pointer from a ccc to aaa or bbb at compile time. In an earlier example, we spoke of functions from two interfaces having similar names. The same rules stated there apply here also.

a.cs
class zzz
{
public static void Main()
{
}
void abc(ccc c)
{
c.aa(1);
c.aa((byte)1);
((aaa)c).aa(1);
((bbb)c).aa(1);
}
}
interface aaa
{
void aa(byte i);
}
interface bbb
{
void aa(short i);
}
interface ccc : aaa , bbb
{
}

Compiler Error
a.cs(8,1): error CS0121: The call is ambiguous between the following methods or properties: 'bbb.aa(short)' and 'aaa.aa(byte)'
a.cs(9,1): error CS0121: The call is ambiguous between the following methods or properties: 'bbb.aa(short)' and 'aaa.aa(byte)'

We have a similar problem again. c.aa(1) does not know which function aa to call. C# could convert the 1 an int, either to a short or a byte. Thus the ambiguity. Even if we cast the 1 to a byte, for some reason, C# yet gives us an error. The only way out is like what we did earlier, explicitly cast your way out of trouble. When we cast, we are restricting ourselves to only one method and thus no ambiguity.

a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
void aa();
}
interface bbb : aaa
{
new void aa();
}
interface ccc : aaa
{
void cc();
}
interface ddd : bbb , ccc
{
}
class eee : ddd
{
}

Compiler Error
a.cs(22,7): error CS0535: 'eee' does not implement interface member 'bbb.aa()'
a.cs(22,7): error CS0535: 'eee' does not implement interface member 'ccc.cc()'
a.cs(22,7): error CS0535: 'eee' does not implement interface member 'aaa.aa()'


The interface aaa has one function aa. The interface bbb is derived from aaa and also has one function called aa. The keyword new informs the C# compiler that, it has hidden or has nothing to do with the function aa in interface aaa. Remember in interfaces, we cannot write any code. The interface ccc also derives from aaa but does not have a function called aa. Then we are creating another interface ddd which derives from both bbb and ccc. The class eee is then derived from interface ddd.  We get three errors as we have to implement three functions in class eee. The interface ccc brings in two functions. One cc and the other aa from interface aa. The interface bbb has only one function, aa which is different from the aa which is present in interface aaa, thanks to the keyword new which is optional.

a.cs
class zzz
{
public static void Main()
{
aaa a = new eee();
a.aa();
bbb b = new eee();
b.aa();
ccc c = new eee();
c.aa();
ddd d = new eee();
d.aa();
eee e = new eee();
//e.aa();
((aaa)d).aa();
((bbb)d).aa();
((ccc)d).aa();
((ddd)d).aa();
}
}
interface aaa
{
void aa();
}
interface bbb : aaa
{
new void aa();
}
interface ccc : aaa
{
void cc();
}
interface ddd : bbb , ccc
{
}
class eee : ddd
{
void aaa.aa()
{
System.Console.WriteLine("aa aaa");
}
void bbb.aa()
{
System.Console.WriteLine("aa bbb");
}
public void cc()
{
System.Console.WriteLine("cc");
}
}

Output
aa aaa
aa bbb
aa aaa
aa bbb
aa aaa
aa bbb
aa aaa
aa bbb

With or without the keyword new, the output remains the same. By adding the keyword new, all that we have achieved is removal of the warning. Lets explain the above program step by step.
We have implemented the three functions that class eee needed. We could have implemented only one aa, and then in every case that one aa, would have been called. In this case we need two aa functions. One for the interface aaa and the other for the interface bbb. As we need a separate function aa for each interface we will land up having two of them. Thus we need to preface them with the name of the interface.

We are creating objects that look like all our interfaces and initializing them to an object that looks like class eee. The object a that looks like interface aaa,  will obviously call the aa of interface aaa. The object b that looks like interface bbb will call the aa of interface aaa implemented in class eee. The object c, that looks like ccc is derived from interface aaa and thus it will call the function aa of interface aaa. All of this is obvious. Now d looks like ddd which is derived from ccc and bbb. The reason it will call the aa of bbb and not of aaa is because we have asked it to hide the function aa of interface aaa. Once a function is hidden, it will remain hidden forever in all the access paths. Thus function aa of interface bbb hides the function aa of interface aaa even in interface ccc.

The casting gives us the same answer as above. In the first case, cast d, a ddd looks alike to an aaa. Thus the aa from aaa gets called. In the second case it calls the aa of bbb. Just like before, when we cast c to a ccc, it calls the aa form aaa . Now we cast c to a ddd, it can call either the function aa from bbb or function aa from aaa. In this case it chooses to call the aa from bbb as its aa hides the aa of interface aaa.

To sum up, if a function is hidden from one access path, it is hidden from all.

A little later in this chapter, we will show you that structures can also implement from an interface.This process of implementing all the functions is called interface mapping.

a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
void a1();
}
interface bbb : aaa
{
new int a1
{
set;
}
}
class ccc : bbb
{
void aaa.a1()
{
}
int bbb.a1 {
set
{
}
}
}
class ddd: bbb
{
public void a1() {}
int bbb.a1
{
set
{
}
}
}
class eee: bbb
{
void aaa.a1()
{
}
public int a1
{
set
{
}
}
}

The interface aaa has one function a1 which clashes with the name of the property in interface bbb. We have three ways to create a class which is derived from bbb. In the first case ccc, we are explicitly qualifying with the name of interface. In the second case of ddd, we are qualifying only the property and not the function. In the third case i.e. class eee, we do the reverse. Thus one of the a1or both must be qualified or else it will result in an error.

a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
void a1();
}
interface bbb : aaa
{
void a2();
}
interface ccc : aaa
{
void a3();
}
class ddd : aaa,bbb,ccc
{
void bbb.a1()
{
}
public void a2()
{
}
public void a3()
{
}
}

Compiler Error
a.cs(21,6): error CS0539: 'bbb.a1' in explicit interface declaration is not a member of interface
a.cs(19,7): error CS0535: 'ddd' does not implement interface member 'aaa.a1()'

Both interfaces bbb and ccc derive from interface aaa. Class ddd derives from three interfaces aaa and bbb and ccc. In class ddd, we have only 3 functions, a1, a2 and a3 that come from aaa, bbb and ccc respectively. Even though interface bbb derives from aaa, it does not carry a1 into class ccc. So, we cannot write bbb.a1 in class ccc. Hence, we have only one a1 from interface aaa in class ccc and none from interfaces bbb and ccc. This proves that C# forgets the interfaces bbb and ccc are derived from. It also means that bbb and ccc cannot have their own implementations of a1.

a.cs
class zzz
{
public static void Main()
{
aaa a = new ccc();
a.a1();
}
}
interface aaa
{
void a1();
}
class bbb
{
public void a1()
{
System.Console.WriteLine("bbb a1");
}
}
class  ccc : bbb , aaa
{
}

Output
bbb a1

The class ccc derives from bbb and aaa. The function a1 from interface aaa is implemented by class bbb and not by ccc. No one cares as long as there is a function a1 somewhere. The function a1, in this case, can be in the actual class or in the base class.

a.cs
class zzz
{
public static void Main()
{
bbb b = new ccc();
b.a1();
ccc c = new ccc();
c.a1();
aaa a = new ccc();
a.a1();
aaa aa = new bbb();
aa.a1();
}
}
interface aaa
{
void a1();
}
class bbb : aaa
{
public void a1()
{
System.Console.WriteLine("bbb a1");
}
}
class  ccc : bbb
{
new public void a1() {
System.Console.WriteLine("ccc a1");
}

Output
bbb a1
ccc a1
bbb a1
bbb a1

In this case, class ccc is derived from class bbb, which in turn is derived from interface aaa. Both the classes implement the function a1. The question on our minds is from which class will the function a1 be called. Both b and c are initialized to an object that looks like ccc. b.a1() will obviously call the function a1 from bbb and c.a1() will call it from ccc. Saying the same thing over and over again like a malfunctioning record disk is trying but essential.

Objects a and aa look like aaa but are initialized to objects that look like ccc and bbb respectively. It does not seem to make any difference as each time the function a1 gets called from the base class bbb and not from the derived class ccc or the class that we have initialized the object to.
This means that the derived class cannot alter the interface mappings it receives from the base class. The mapping of function a1 is to the class bbb as bbb was derived from the interface. Class ccc cannot change this fact.

a.cs
class zzz
{
public static void Main()
{
bbb b = new ccc();
b.a1();
bbb b1 = new bbb();
b1.a1();
ccc c = new ccc();
c.a1();
aaa a = new ccc();
a.a1();
aaa aa = new bbb();
aa.a1();
}
}
interface aaa
{
void a1();
}
class bbb : aaa
{
public virtual void a1()
{
System.Console.WriteLine("bbb a1");
}
}
class  ccc : bbb
{
public override void a1()
{
System.Console.WriteLine("ccc a1");
}
}

Output
ccc a1
bbb a1
ccc a1
ccc a1
bbb a1

We have made two changes in our program. We made the function a1 virtual in the class bbb and also, in the class ccc, we declared a1 with the override modifier. Whenever we declare a function to be virtual, the derived classes will and can override it. The modifier override has the opposite meaning over new. It means do not create a new function but override the base class definition.

Objects b and b1 both look like bbb but are initialized to objects that look like ccc and bbb respectively. When we write b.a1(), C# first looks into the class bbb as that is the data type of b. Here the function a1 is marked virtual, so C# now asks ‘what was b initialized by’? As the answer is an object that looks like ccc, C# now looks at the class ccc for the function a1. As it is marked override, C# will execute the function a1 from  class ccc and not bbb. If the override was missing, the default is new, and the function will be called from the data type of the object i.e. bbb.

As object b1 has been initialized by an object that looks like bbb, C# will call a1 from class bbb only. The object c follows the earlier specified rules. As for objects a and aa, both look like interface aaa which has no code for the function aaa. Here the object used to initialize will decide the class a1 will be called from. This is due to the explanation above as a1 is marked virtual in class bbb and override in class ccc.

a.cs
class zzz
{
public static void Main()
{
}
}
interface ppp
{
void a1();
}
interface aaa
{
void a1();
}
class bbb : aaa , ppp
{
public virtual void aaa.a1()
{
System.Console.WriteLine("bbb a1");
}
}
class  ccc : bbb
{
public override void a1() {
System.Console.WriteLine("ccc a1");
}

Compiler Error
a.cs(17,21): error CS0106: The modifier 'public' is not valid for this item
a.cs(17,21): error CS0106: The modifier 'virtual' is not valid for this item

Lets make matters worse. We have an interface ppp which also brings in a function called a1. The class bbb also derives from ppp. Thus we have two a1 functions and we have to explicitly qualify them. Unfortunately we cannot add the qualifier virtual here. The only way out is as follows.

a.cs
class zzz
{
public static void Main()
{
aaa a = new ccc();
a.a1();
aaa aa = new bbb();
aa.a1();
}
}
interface ppp
{
void a1();
}
interface aaa
{
void a1();
}
class bbb : aaa , ppp
{
void aaa.a1()
{
aa1();
}
void ppp.a1()
{
}
public virtual void aa1()
{
System.Console.WriteLine("aa1");
}
}
class  ccc : bbb
{
public override void aa1()
{
System.Console.WriteLine("aa1 ccc");
}
}

Output
aa1 ccc
aa1

What we have done here is that in the a1 function of aaa we have called the function aa1. So in other words, a1 simply calls aa1. We have made aa1 virtual such that each time aa1 is called, the question asked will be - which object was used at the time of initialization? Depending upon the type of object, the relevant function aa1 would be executed. Thus we get the same answer as earlier. If we have to reimplement an interface, you can look at the example earlier. C# forgets about the initial derivation.


a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
void a1();
void a2();
}
abstract class bbb : aaa
{
}

Compiler Error
a.cs(12,16): error CS0535: 'bbb' does not implement interface member 'aaa.a1()'
a.cs(12,16): error CS0535: 'bbb' does not implement interface member 'aaa.a2()'

Whenever we have a abstract class deriving from an interface, the class must implement all the methods of the interface as follows.

a.cs
class zzz
{
public static void Main()
{
}
}
interface aaa
{
void a1();
void a2();
}
abstract class bbb : aaa
{
public void a1()
{
}
public abstract void a2();
}

If the abstract class does not want to implement all the members of the interface, it has to mark the functions as abstract and public. The class deriving from bbb will now have to supply the code of the class bbb

Structures

a.cs
class zzz
{
public static void Main()
{
xxx x = new xxx(10);
System.Console.WriteLine(x.i);
x.abc();
}
}
struct xxx
{
public int i;
public xxx( int j)
{
i = j;
}
public void abc()
{
System.Console.WriteLine("abc");
}
}

Output
10
abc

A structure or struct to be precise is similar to a class in many ways. A struct can contain fields, methods etc. If a struct and class were 100 per cent similar, then why have both? We will now explain the differences between a struct and a class. Unless otherwise stated, they share the same features.

a.cs
class zzz
{
public static void Main()
{
}
}
struct xxx
{
public int i = 10;
}

Compiler Error
a.cs(9,12): error CS0573: 'xxx.i': cannot have instance field initializers in structs

In a class we are allowed to create a field/variable and initialize it at the same time. A structure cannot contain such initializations. Thus these fields must be initialized either through functions or by using the object itself. Fields cannot be given initial values at the time of creation.

a.cs
class zzz
{
public static void Main()
{
xxx  a = new xxx();
}
}
struct xxx
{
public int i;
public xxx()
{
}
}

Compiler Error
a.cs(11,8): error CS0568: Structs cannot contain explicit parameterless constructors

A class can contain many constructors. And even if we do not have any, C# supplies a free constructor with no parameters. It's very different with structures. You cannot have  a constructor with no parameters. If you do, you will get the above error. Thus C# lets you have as many constructors as you like but none without parameters.

a.cs
class zzz
{
public static void Main() {
xxx  a = new xxx(10);
}
}
struct xxx
{
public int i;
public xxx(int p) { }
}

Compiler Error
a.cs(10,8): error CS0171: Field 'xxx.i' must be fully assigned before control leaves the constructor

A small problem here. As mentioned earlier we cannot initialize a field like we do in a class. Hence C# insists on constructors that accept parameters to initialize fields; at the end of the constructor if you have not initialized the fields in the structure, we get the above error. Thus C# actually reads our code and makes sure that the constructor initializes all the fields in the structure.
a.cs
class zzz
{
public static void Main()
{
xxx  a = new xxx(10);
}
}
struct xxx
{
public int i,j;
public xxx(int p) {
i = p;
}
}

Compiler Error
a.cs(11,8): error CS0171: Field 'xxx.j' must be fully assigned before control leaves the constructor

The keyword shown in all the above errors is fields.

a.cs
class zzz
{
public static void Main()
{
xxx  a = new xxx(10);
}
}
struct xxx
{
public int i,j;
public xxx(int p)
{
i = p;
j = 0;
}
}
We get no error as the structure has two fields and we have now initialized both of them.

a.cs
class zzz
{
public static void Main()
{
xxx  a = new xxx();
System.Console.WriteLine(a.i);
}
}
struct xxx
{
public int i;
}

Compiler Warning
a.cs(11,12): warning CS0649: Field 'xxx.i' is never assigned to, and will always have its default value 0

Output
0

If we do not have any constructors, we get no error. As we have not initialized the field i, in the constructor, we have none. C# gives you a warning and for the sake of your sanity, initializes i to 0.

a.cs
class zzz
{
public static void Main()
{
xxx  a = new xxx();
System.Console.WriteLine(a.i);
}
}
struct xxx
{
public int i;
}
struct yyy : xxx
{
}

Compiler Error
a.cs(13,14): error CS0527: 'xxx' : type in interface list is not an interface

A structure yyy cannot be derived from another structure. A useful feature of a class was the fact that we could share/use code from other classes. A structure does not support the concept of inheritance. Had xxx been a class we would have received the same error.

a.cs
class zzz
{
public static void Main()
{
xxx  a = new yyy();
}
}
interface xxx
{
}
struct yyy : xxx
{
}

The previous error message gave us a hint . It expected xxx to be a interface. Thus we can derive a structure from an interface. As xxx has no members we do not have to implement any code in our structure.

a.cs
class zzz
{
public static void Main()
{
xxx  a = new yyy();
}
}
struct yyy
{
}
class xxx : yyy
{
}

Compiler Error
a.cs(11,7): error CS0509: 'xxx' : cannot inherit from sealed class 'yyy'

As a structure could not inherit from a class, the reverse is also true. xxx cannot inherit from a structure yyy. Internally a structure behaves as a sealed class as the error message reads. For those who came in late, a sealed class cannot be used a base class.

a.cs
class zzz
{
public static void Main()
{
}
}
sealed struct yyy
{
}

Compiler Error
a.cs(7,15): error CS0106: The modifier 'sealed' is not valid for this item

You cannot declare a structure as sealed as they are by definition sealed. If you add the word sealed as we have done, C# complains about the fact that we are repeating the same modifier again and nobody likes repetition.

a.cs
class zzz
{
public static void Main()
{
}
}
abstract struct yyy
{
}

Compiler Error
a.cs(7,17): error CS0106: The modifier 'abstract' is not valid for this item

As C# does not like repetition, we have to bow to its wishes. But you do not have an option. We are free to repeat ourselves with you as many times as we like. So let us indulge ourselves. A structure as mentioned earlier cannot be used as a base class i.e. be used in a derivation. An abstract modifier, means an incomplete entity which cannot be used directly but only as a base class. It makes no sense for a structure to use the modifier abstract.

In the same vein, function in a structure cannot be marked abstract or virtual as these are concepts, which apply to derived classes only.

a.cs
class zzz
{
public static void Main()
{
}
}
protected struct xxx {  }

Compiler Error
a.cs(7,1): error CS1527: Namespace elements cannot be explicitly declared as private or protected

A structure cannot be derived from and the modifier protected deals with the visibility of members from derived classes. Replacing protected with private results in the same error.

a.cs
class zzz
{
public static void Main()
{
yyy  a = new yyy();
System.Console.WriteLine(a.ToString());
}
}
struct yyy
{
}

Output
yyy

However every structure like a class is implicitly derived from the class Object and thus has the functions Object contains. In this case ToString returns the name of the derived class.

a.cs
class zzz
{
public static void Main()
{
yyy  a = new yyy();
System.Console.WriteLine(a.ToString());
}
}
struct yyy : System.Object
{
}


Compiler Error
a.cs(9,14): error CS0527: 'System.Object' : type in interface list is not an interface

How do we explain the above error? We just mentioned earlier that as a structure inherits from the class Object and we called a function called ToString from the class Object. However we cannot derive from Object explicitly as the compiler insists on the name of an  interface and Object is a name of a class. These little quirks make learning C# difficult. If you replace the word struct with class in the above example, you will not get an error.

A computer has lots of memory. We logically divide this memory into two, the stack and the heap. Memory denoted as the stack lives as long as the function lives and heap memory lives as long as your program runs. Objects, instances of a class are allocated on the heap. They will live for a long time. They are also called reference objects. Structures are allocated on the stack by new and live for a shorter duration. We call them value objects. This means that a structure directly represents the data where as a object contains a reference to the data. Structures thus offer a more efficient access to variables than classes. Int, bool and all the other basic data types are implemented as structures.

a.cs
class zzz
{
public static void Main()
{
xxx x,y;
yyy a,b;
x = new xxx(1); y = new xxx(2);
a = new yyy(1); b = new yyy(2);
System.Console.WriteLine(x.i + " " + y.i + " " + a.i + " " + b.i);
x = y; a = b;
System.Console.WriteLine(x.i + " " + y.i + " " + a.i + " " + b.i);
x.i = 100; a.i = 200;
System.Console.WriteLine(x.i + " " + y.i + " " + a.i + " " + b.i);
}
}
class yyy
{
public int i;
public yyy(int j)
{
i = j;
}
}
struct xxx
{
public int i;
public xxx(int j)
{
i = j;
}
}

Output
1 2 1 2
2 2 2 2
100 2 200 200

We have created two objects a and b which look like a class yyy and two structures x and y which look like xxx. In the constructors of each, we are initializing the field i to 1 and 2 respectively. Then we are equating the object a to b and the structure x to y. This will set the i of x to 2 from 1 and also the i of a to 2. Thus the second WriteLine displays all two's. We are now changing the i of x, which is a structure to 100 and we realize that the i of y, the structure it was initialized to remains the same. Thus x.i is 100 and y.i remains at 2.

For classes it does not work the same way. Changing a.i to 200, somehow changes the i of b which a was initialized to, also to 200. This could only be possible if when we equate structures, each has its own copy of the data. When we equate objects, no copying takes place and now object a refers to object b in memory. Both a and b represent the same object. Changing a changes b. A little later, we dwell on this concept further.

The same rules of passing parameters to a function i.e. out and ref that apply to an int also apply to a structure as int is also a structure internally.

a.cs
class zzz
{
public static void Main()
{
xxx x;
yyy a;
x=null;
a=null;
}
}
class yyy
{
}
struct xxx
{
}

Compiler Error
a.cs(7,3): error CS0037: Cannot convert null to 'xxx' because it is a value type

In computer programming, a large number of times we do not know the value of a variable at a point in time. These variables are given a value of null. Null can be only applied to objects of reference types and not value types.

a.cs
class zzz
{
public static void Main()
{
}
}
struct xxx
{
public ~xxx()
{
}
}

Compiler Error
a.cs(9,9): error CS0575: Only class types can contain destructors

After a long time, we get an error message that is readable. Structures are created on the stack and die when we reach the closing brace. There is thus no memory management to be done from the point of view of the programmer. The structure life cycle is very deterministic and hence no destructors are permitted.

No comments:

Post a Comment

No String Argument Constructor/Factory Method to Deserialize From String Value

  In this short article, we will cover in-depth the   JsonMappingException: no String-argument constructor/factory method to deserialize fro...