Google
 

Tuesday, September 11, 2007

How new and override directives affect interface and class hierarchies in C#

The following sample codes will explain how new and override directives affect interface and class hierarchies.

1.override
If you wish to override the base-class method when instantiating a base-class type with a subclass reference, you need to use the override directive.

Sample code:
public interface ITrace
{
string TraceSelf();
}
public class A:ITrace
{
public virtual string TraceSelf()
{
return "A";
}
}
public class B:A
{
public override string TraceSelf()
{
return " B";
}
}
public class C:B
{
public override string TraceSelf()
{
return " C";
}
}

Expected Condition:
All following test cases will be pass.

Test Code:
[TestFixture]
public class TestInterfaceAndClassHierarchiesOverride
{
[Test]
public void TestMethod()
{
ITrace trace
= new A();
Assert.AreEqual(
"A",trace.TraceSelf());
}
[Test]
public void TestMethod1()
{
ITrace trace
= new B();
Assert.AreEqual(
" B",trace.TraceSelf());
// The B only override the implementation of A, and it do inherit the the implementation of the interface of ITrace. // So the value traced is "B" not "A" by interface ITrace.
// This is the usual condition we encountered.
}
[Test]
public void TestMethod2()
{
ITrace trace
= new C();
Assert.AreEqual(
"C",trace.TraceSelf ());
}
[Test]
public void TestMethod3()
{
A a
= new C();
Assert.AreEqual(
"C",a.TraceSelf ());
}
[Test]
public void TestMethod4()
{
A a
= new B();
Assert.AreEqual(
"B",a.TraceSelf ());
}
}


2.New
If you want to provide the base-class behavior instead, use the new directive , with or without virtual, at the base class.

Sample Code:
public interface ITrace
{
string TraceSelf();
}
public class A:ITrace
{
public virtual string TraceSelf() // Here the virtual is optional
{
return " A";
}
}
public class B:A
{
public new string TraceSelf()
{
return "B" ;
}
}
public class C:B
{
public new string TraceSelf()
{
return "C" ;
}
}

Expected result:
All following test cases will be pass.

Test Code:
[TestFixture]
public class TestInterfaceAndClassHierarchiesNew
{
[Test]
public void TestMethod()
{
ITrace trace
= new A();
Assert.AreEqual(
"A",trace.TraceSelf());
}
[Test]
public void TestMethod1()
{
ITrace trace
= new B();
Assert.AreEqual(
" A",trace.TraceSelf());
// To trace the value from B by interface ITrace is "A" not "B".
// The method of A implemented the ITrace interface has been newed by B.
// So the B class has not implemented the ITrace interface.

}
[Test]
public void TestMethod2()
{
ITrace trace
= new C();
Assert.AreEqual(
" A",trace.TraceSelf());

A a
= new C();
Assert.AreEqual(
" A",a.TraceSelf());
}
[Test]
public void TestMethod3()
{
A a
= new C();
Assert.AreEqual(
" A",a.TraceSelf());
// The inherited method from A has been newed by C. // So The value traced from C object by A is "A" not "C".
}
[Test]
public void TestMethod4()
{
A a
= new B();
Assert.AreEqual (
"A",a.TraceSelf());
}
}

3.Interface hierarchies

Sample Code:
public interface ITrace
{
string TraceSelf();
}
public class A:ITrace
{
public virtual string TraceSelf()
{
return "A";
}
}
public class B:A,ITrace
{
public new string TraceSelf()
{
return "B";
}
}
public class C:B,ITrace
{
public new string TraceSelf()
{
return "C";
}
}

Expected Result:
All following test cases will be pass.

Test Code:
[TestFixture]
public class TestInterfaceAndClassHierarchiesNewWithInterfaceHierarchie
{
[Test]
public void TestMethod()
{
ITrace trace
= new A();
Assert.AreEqual(
"A",trace.TraceSelf());
}
[Test]
public void TestMethod1()
{
ITrace trace
= new B();
Assert.AreEqual(
"B",trace.TraceSelf ()); // The B does implement the ITrace interface, so the value traced by the interface ITrace is "B" not "A", // although B has its own implementation of ITrace instead of A's with the new directive
}
[Test]
public void TestMethod2()
{
ITrace trace
= new C();
Assert.AreEqual(
"C",trace.TraceSelf ());
}
[Test]
public void TestMethod3()
{
A a
= new C();
Assert.AreEqual(
"A",a.TraceSelf ());
// Because C newed the method inherited from A, // so the value traced by the A from C object is "A" not "C"
}
[Test]
public void TestMethod4()
{
A a
= new B();
Assert.AreEqual(
"A ",a.TraceSelf());
}
}

--
Happy day, happy life!

No comments: