Interfaces, Inheritance and the 'new' keyword - c#

I am wondering if someone can please explain this to me:
class Program
{
static void Main()
{
AnotherDerivedClass d = new AnotherDerivedClass();
Console.WriteLine(d.PrintMessage());
IMsg m = d as IMsg;
//Why this prints BaseClass.
//How does it know that IMsg is implemented in the BaseClass.
Console.WriteLine(m.PrintMessage());
IMsg n = d as DerivedClass;
//Why this prints BaseClass and not DerivedClass
Console.WriteLine(n.PrintMessage());
Console.Read();
}
}
public interface IMsg
{
string PrintMessage();
}
public class BaseClass : IMsg
{
public string PrintMessage()
{
return "BaseClass";
}
}
public class DerivedClass : BaseClass
{
public new string PrintMessage()
{
return "DerivedClass";
}
}
public class AnotherDerivedClass : DerivedClass
{
public new string PrintMessage()
{
return "AnotherDerivedClass";
}
}

You have replaced the implementation in your derived classes, not overridden them. If you use the BaseClass, the original implementation will be used.
You need to make the method in the base virtual:
public class BaseClass : IMsg
{
public BaseClass()
{
}
public virtual string PrintMessage()
{
return "BaseClass";
}
}
and override in the derived class:
public class DerivedClass : BaseClass
{
public DerivedClass()
{
}
public override string PrintMessage()
{
return "DerivedClass";
}
}
to get the behaviour you specified.

Related

How to implement WebPage pattern and add Interface in save class test

Please see this structure (from here):
public abstract class AbstractPage<T> where T : AbstractPageEmenetsMap, new()
{
protected readonly string url;
protected VendorInfo vendorInfo;
public AbstractPage(VendorInfo vendorInfo)
{
this.vendorInfo = vendorInfo;
this.url = this.vendorInfo.Url;
}
public void Navigate()
{
WebDriver.Driver.Navigate().GoToUrl(this.url);
}
protected T Map
{
get { return new T(); }
}
}
public abstract class AbstractPage<M, V> : AbstractPage<M>, ITest
where M : AbstractPageEmenetsMap, new()
where V : AbstractPageValidator<M>, new()
{
public AbstractPage(VendorInfo vendorInfo)
: base(vendorInfo) { }
public V Validate()
{
return new V();
}
public void Login();
{
throw new System.NotImplementedException();
}
public void Logout();
{
throw new System.NotImplementedException();
}
}
And i want to add interface with some operations
public interface ITest
{
void Login();
void Logout();
}
Now this is Son class:
public class GmailPage : AbstractPage<GmailPageElementsMap, GmailPageValidator>, ITest
{
public GmailPage() : base("http:...") { }
}
Class that holds all the elements:
public IWebElement EmailAddressTextBox
{
get
{
return WebDriver.WebDriverWait.Until(ExpectedConditions.ElementIsVisible(By.Id("identifierId")));
}
}
And validator:
public class GmailPageValidator : AbstractPageValidator<GmailPageElementsMap>
{
}
As you can see i implement ITest from my Gmail class but i don't received any compile error although i do not add this 2 interface methods (Login and Logout).
This is because those methods are implemented in the parent AbstractPage. If you want to force GmailPage (and all other derived classes) to implement Login() and Logout() declare them as abstract in the parent AbstractPage class
public abstract class AbstractPage<M, V> : AbstractPage<M>, ITest
where M : AbstractPageEmenetsMap, new()
where V : AbstractPageValidator<M>, new()
{
public AbstractPage(VendorInfo vendorInfo) : base(vendorInfo) { }
public V Validate()
{
return new V();
}
public abstract void Login();
public abstract void Logout();
}
And override in GmailPage
public class GmailPage : AbstractPage<GmailPageElementsMap, GmailPageValidator>
{
public GmailPage() : base("http:...") { }
public override void Login()
{
throw new System.NotImplementedException();
}
public override void Logout()
{
throw new System.NotImplementedException();
}
}

Polymorphism, inheritance and generic C# : Cannot cast subclass into supertype

I have a problem with abstract class and generic in c# (I usually code in Java) : here is the code I would like to use :
public interface InterfaceResult {...}
public abstract class Result : InterfaceResult {...}
public class ResultA : Result {...}
public class ResultB : Result {...}
public interface InterfaceKing { InterfaceResult function();}
public abstract class King : InterfaceKing {
public abstract Result function();
}
public class KingA : King {
public override ResultA function(){...}
}
public class KingB : King {
public override ResultB function(){...}
}
but that doesn t work : Visual Studio want for KingA and KingB to return an instance of Result with function(). If i use "new" instead of override, VS say I don t implement the required method (i need to use override).
So I tried with generic and it s not better
public abstract class Result { }
public class ResultA : Result { }
public class ResultB : Result { }
public interface IKing<T> {T function(); }
public abstract class King<Result> : IKing<Result>
{
public abstract Result function();
public static implicit operator King<Result>(KingB v)
{
return v; // generate StackOverflow Exception
}
public static implicit operator King<Result>(KingA v)
{
throw new NotImplementedException();
}
}
public class KingA : King<ResultA>
{
public override ResultA Get()
{
return new ResultA();
}
}
public class KingB : King<ResultB>
{
public override ResultB Get()
{
return new ResultB();
}
}
public class Test
{
King<Result> a = new KingA(); // allowed by public static implicit operator King<Result>(KingA v)
King<Result> b = new KingB(); // allowed by public static implicit operator King<Result>(KingB v)
KingA ka = new KingA();
List<King<Result>> lista = new List<King<Result>>();
public void test()
{
lista.Add(ka);
}
}
How can i make this work ? I can t find any solution nor any good or complete example.
Moving from "full interface" to "no interface" (for lack of better terms) all that work (this Main works fine)
static void Main ()
{
King a = new KingA ();
King b = new KingB ();
KingA ka = new KingA ();
List<King> list = new List<King> ();
list.Add (a);
list.Add (b);
list.Add (ka);
}
"full interface"
public interface InterfaceResult { }
public abstract class Result : InterfaceResult { }
public class ResultA : Result { }
public class ResultB : Result { }
public interface InterfaceKing { InterfaceResult Function (); }
public abstract class King : InterfaceKing
{
public abstract InterfaceResult Function ();
}
public class KingA : King
{
public override InterfaceResult Function () => new ResultA ();
}
public class KingB : King
{
public override InterfaceResult Function () => new ResultA ();
}
"mixed (less interface)"
public abstract class Result { }
public class ResultA : Result { }
public class ResultB : Result { }
public interface IKing { Result Function (); }
public abstract class King : IKing
{
public abstract Result Function ();
}
public class KingA : King
{
public override Result Function () => new ResultA ();
}
public class KingB : King
{
public override Result Function () => new ResultB ();
{
return new ResultB ();
}
}
"no interface"
public abstract class Result { }
public class ResultA : Result { }
public class ResultB : Result { }
public abstract class King
{
public abstract Result Function ();
}
public class KingA : King
{
public override Result Function () => new ResultA ();
}
public class KingB : King
{
public override Result Function () => new ResultB ();
}
Using covariance
See .net fiddler here. Read more about Covariance and Contravariance
public abstract class Result { }
public class ResultA : Result { }
public class ResultB : Result { }
public interface IKing<out T> where T : Result {}
public abstract class King<T> : IKing<T> where T : Result
{
public abstract T Get();
}
public class KingA : King<ResultA>
{
public override ResultA Get()
{
return new ResultA();
}
}
public class KingB : King<ResultB>
{
public override ResultB Get()
{
return new ResultB();
}
}
public class TestClass
{
King<ResultA> a = new KingA(); // allowed by public static implicit operator King<Result>(KingA v)
King<ResultB> b = new KingB(); // allowed by public static implicit operator King<Result>(KingB v)
KingA ka = new KingA();
List<IKing<Result>> lista = new List<IKing<Result>>();
public void Test()
{
lista.Add(ka);
}
}

Abstract factory implementation within C# application

I'd like to implement abstract factory design pattern. I add this snippet :
public class Class1
{
static Ete _ete;
static Hiver _hiver;
public static void Main(Clothes cl)
{
_ete = cl.CreateEteClothes();
_hiver = cl.CreateHiverClothes();
Console.WriteLine(_ete.GetMarque());
Console.ReadKey();
Console.WriteLine(_hiver.GetMarque());
Console.ReadKey();
}
}
public abstract class Clothes
{
public abstract Ete CreateEteClothes();
public abstract Hiver CreateHiverClothes();
}
public abstract class ItalianFactory: Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtJuve();
}
public override Hiver CreateHiverClothes()
{
return new PullJuve();
}
}
public abstract class FrenchFactory : Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtPsg();
}
public override Hiver CreateHiverClothes()
{
return new PullPsg();
}
}
public abstract class TunisianFactory : Clothes
{
public override Ete CreateEteClothes()
{
return new TShirtCa();
}
public override Hiver CreateHiverClothes()
{
return new PullCa();
}
}
public abstract class Ete
{
public abstract string GetMarque();
}
public abstract class Hiver
{
public abstract string GetMarque();
}
public class TShirtJuve: Ete
{
public override string GetMarque()
{
return "Juventus T shirt";
}
}
public class TShirtPsg : Ete
{
public override string GetMarque()
{
return "PSG T shirt";
}
}
public class TShirtCa : Ete
{
public override string GetMarque()
{
return "club africain T shirt";
}
}
public class PullJuve : Hiver
{
public override string GetMarque()
{
return "Juventus Pull";
}
}
public class PullPsg : Hiver
{
public override string GetMarque()
{
return "PSg Pull";
}
}
public class PullCa : Hiver
{
public override string GetMarque()
{
return "Club africain Pull";
}
}
I'd like to test this implementation, but I get an exception indicates that the signature of main method is not acceptable.
So How can I fix my code to test this design pattern implementation?
You have public static void Main(Clothes cl)
This should be static void Main(string[] args) as this is the entry point for the application and there can be only one entry point. See the .NET documentation for more info.
A method's signature usually consists of the methods name, return type, and parameters. Your application is expecting the correct signature for the Main method, hence it's giving you this exception.

c# Cannot call abstract generic method from static base class method [duplicate]

I'm trying to create an abstract generic class which inherits from another abstract generic class.
Here's what I have so far
public abstract class BaseClass {
public long Id { get; private set; }
public BaseClass(long id) {
this.Id = id;
}
}
public abstract class BaseClass<T> : BaseClass where T : BaseClass {
protected BaseClass(long id)
: base(id) {
}
public static T Get(long id) {
T item;
return TryGet(id, out item) ? item : default(T);
}
public static bool TryGet(long id, out T item) {
item = null; // This is where I call the cache but for this example I've removed so it will compile
if (item != null) { return true; }
else {
// Call TryGetFallback method
return false;
}
}
protected abstract T TryGetFallback(long id);
}
public abstract class DerivedClass : BaseClass<DerivedClass> {
public String Name { get; private set; }
public DerivedClass(long id, String name)
: base(id) {
this.Name = name;
}
}
public class DerivedDerivedClass : DerivedClass {
protected override DerivedDerivedClass TryGetFallback(long id) {
// Handle the try get fallback
}
}
The TryGetFallback method on the DerivedDerivedClass causes a compiler error.
First you need to fix your BaseClass<T> implementation to not have a recursive type constraint.
public abstract class BaseClass<T> : BaseClass where T : new() {
//snip
}
Then you can use it in your derived class, for example I will make it use int for the generic type parameter:
public abstract class DerivedClass : BaseClass<int> {
//snip
}
And now if you compile it will warn you that 'DerivedDerivedClass' does not implement inherited abstract member 'BaseClass<int>.TryGetFallback(long)'
Thanks for the tips #DavidG it's helped me to solve the problem with the following code
public abstract class BaseClass {
public long Id { get; private set; }
public BaseClass(long id) {
this.Id = id;
}
}
public abstract class BaseClass<T> : BaseClass where T : BaseClass<T>, new() {
protected BaseClass(long id) : base(id) { }
public static T Get(long id) {
T item;
return TryGet(id, out item) ? item : default(T);
}
public static bool TryGet(long id, out T item) {
item = null; // Try to get item from cache here
if (item != null) { return true; }
else {
T obj = new T();
item = obj.TryGetFallback(id);
return item != null;
}
}
protected abstract T TryGetFallback(long id);
}
public abstract class DerivedClass<T> : BaseClass<T> where T : DerivedClass<T>, new() {
public String Name { get; private set; }
public DerivedClass() : base(0) { }
public DerivedClass(long id, String name)
: base(id) {
this.Name = name;
}
protected abstract override T TryGetFallback(long id);
}
public class DerivedDerivedClass : DerivedClass<DerivedDerivedClass> {
public DerivedDerivedClass() {
}
protected override DerivedDerivedClass TryGetFallback(long id) {
throw new NotImplementedException();
}
}

can i override a class variable in a sub class and change its type to a sub class

is there a way to override a variable in a subclass, but also change the type to be a subclass of that type.
ie.
public class BaseClass
{
public BaseClass() { }
protected virtual MyBase WorkField { get { return new MyBase(); } }
public int WorkProperty
{
get { return WorkField.Value; }
}
}
public class DerivedClass : BaseClass
{
public DerivedClass():base() { }
/* I get an error here saying that WorkField needs to be MyBase type*/
protected override MyExtend WorkField
{
get
{
return new MyExtend();
}
}
//public new int WorkProperty
//{
// get { return 0; }
//}
}
public class MyBase
{
public int Value = 1;
}
public class MyExtend : MyBase
{
public int value = 20;
}
is there a way to do similar to this, but valid?
so i can have a superClass that does task on MyBase, and then have a subclass that does things on the MyEntend version of it.
without casting it everytime i use it.
There is no reason to change the signature in this case. Just return the derived type:
public class DerivedClass : BaseClass
{
public DerivedClass():base() { }
protected override MyBase WorkField
{
get
{
return new MyExtend();
}
}
//public new int WorkProperty
//{
// get { return 0; }
//}
}
The polymorphic behavior of your subclass will allow you to return it.
For overriding the signature should be of the base base method.
public class BaseClass<T> where T : MyBase, new()
{
public BaseClass() { }
protected virtual T WorkField { get { return new T(); } }
public int WorkProperty { get { return WorkField.Value; } }
}
public class DerivedClass : BaseClass<MyBase>
{
public DerivedClass() : base() { }
// same error occurs as base property is of type "MyBase"
protected override MyExtend WorkField { get { return new MyExtend();
} }
//public new int WorkProperty
//{
// get { return 0; }
//}
}
public class BaseClass<T> where T: MyBase, new()
{
public BaseClass() { }
protected virtual T WorkField { get { return new T(); } }
public int WorkProperty { get { return WorkField.Value; } }
}
public class DerivedClass : BaseClass<MyExtend>
{
public DerivedClass() : base() { }
protected override MyExtend WorkField { get { return new MyExtend(); } }
//public new int WorkProperty
//{
// get { return 0; }
//}
}
public class MyBase
{
public MyBase()
{
}
public int Value = 1;
}
public class MyExtend : MyBase
{
public int value = 20;
}

Categories

Resources