What are some real-world examples of abstract new/virtual/override/abstract keywords?

abstract-class, c#

Solution

`virtual`/`override` is the core polymorphism pair; sounds like you've already cracked these

`abstract` is like `virtual`, but there is no sensible base implementation; use-cases: perhaps a `Stream`, where it is necessary for the actual implementation to do something with the bytes. This forces the class to be `abstract`

`new` should usually be avoided; it breaks polymorphism... the most common case is to re-expose with a more specific signature / return-type (perhaps in a sealed class, since it doesn't get prettier up the chain...) - see `SqlConnection.CreateCommand` (vs `DbConnection.CreateCommand`), or (perhaps more notably) `IEnumerator<T>.Current` (vs `IEnumerator.Current`)

Problem

I'm moving from PHP to C#. In PHP it was simple and straightforward to use abstract classes to create a "cascading override" pattern, basically "the base class method will take care of it unless the inheriting class has a method with the same signature". In C#, however, I just spent about 20 minutes trying out various combinations of the keywords new, virtual, abstract, and override in the base and inheriting classes until I finally got the right combination which does this simple cascading override pattern. So even those the code below works the way I want it, these added keywords suggest to me that C# can do much more with abstract classes. I've looked up examples of these keywords and understand basically what they do, but still can't imagine a real scenario in which I would use them other than this simple "cascading override" pattern. What are some real world ways that you implement these keywords in your day-to-day programming? code that works: ``` using System; namespace TestOverride23433 { public class Program { static void Main(string[] args) { string[] dataTypeIdCodes = { "line", "wn" }; for (int index = 0; index < dataTypeIdCodes.Length; index++) { DataType dataType = DataType.Create(dataTypeIdCodes[index]); Console.WriteLine(dataType.GetBuildItemBlock()); } Console.ReadLine(); } } public abstract class DataType { public static DataType Create(string dataTypeIdCode) { switch (dataTypeIdCode) { case "line": return new DataTypeLine(); case "wn": return new DataTypeWholeNumber(); default: return null; } } //must be defined as virtual public virtual string GetBuildItemBlock() { return "GetBuildItemBlock executed in the default datatype class"; } } public class DataTypeLine : DataType { public DataTypeLine() { Console.WriteLine("DataTypeLine just created."); } } public class DataTypeWholeNumber : DataType { public DataTypeWholeNumber() { Console.WriteLine("DataTypeWholeNumber just created."); } //new public override string GetBuildItemBlock() //base method is erroneously executed //public override string GetBuildItemBlock() //gets error "cannot override inherited member because it is not marked virtual, abstract, or override" public override string GetBuildItemBlock() { return "GetBuildItemBlock executed in the WHOLENUMBER class."; } } } ```

Original source