c# abstract classes -- "one or the other" alternate functions - c#

Here's one, I have an abstract class like this...
public abstract class SpaceshipManager
{
...
public abstract void BuildWith(ParseObject po);
// "Or ..."
public abstract void BuildWith(string label);
...
}
The sense is, the derived classes must implement BuildWith a ParseObject, "OR", they can implement BuildWith using a string.
Now, at the moment I just do this ...
public abstract void BuildWith(object data);
Which is fine - but is there a better way?
Another way to look at it, you could have two methods
BuildKeidranType()
BuildBastionType()
The concept is that derived classes have to implement at least one of these.
Is there any such thing in c#?

You could use generics:
public abstract class SpaceshipManager<T>
{
public abstract void BuildWith(T source);
}
public class StringBuilderSpaceshipManager : SpaceshipManager<ParseObject> { ... }

Well there is nothing like that in c#. Generics could have given you a way out.
But seeing that you are deriving from MonoBehavior, i am assuming it's Unity you are working with, where there are constraints like the class name must be same as the file name etc. etc. which don't give too many options for generic behaviors. So avoiding generic classes and focusing on generic methods.
The following is a very crude example using generics just for fun and might not be much better than your current example where you take the parameter as an object. Nevertheless here goes:
public abstract class SpaceshipManager: MonoBehaviour
{
public void BuildWith<T>(T po)
{
if (ValidateBuildParam<T>())
{
Build<T>(po);
}
}
protected abstract bool ValidateBuildParam<T>();
protected abstract void Build<T>(T type);
}
public class DerivedA : SpaceshipManager
{
protected override void Build<T>(T po)
{
//Build here
}
protected override bool ValidateBuildParam<T>()
{
return (typeof(T) != typeof(ParseObject)) ? false : true;
}
}
public class DerivedB : SpaceshipManager
{
protected override void Build<T>(T po)
{
//Build here
}
protected override bool ValidateBuildParam<T>()
{
return (typeof(T) != typeof(string)) ? false : true;
}
}
Now there are some drawbacks like the following usage wont be incorrect:
SpaceshipManager spMan = new DerivedA();
spMan.BuildWith<int>(5);
This will compile and run but would build nothing. So it would be good if you change the return type of BuildWith, return null if Validation fails or a bool true or false

No, there's no such thing.
If the derived class implemented only one of the overloads, how would the caller know which one is implemented?

NO, such things which you are asking is not available in c#. In c# there is interface but you would have to implement all of the methods in derived class because if you would implement one of those caller would get confused.

As others have already told you, you cannot define abstract methods as optional to be implemented somehow.
If possible, I would suggest defining some kind of common type that can serve as input for the BuildWith method. For example, can the label string also be represented as a ParseObject? If not, can you think of some common abstraction for the two?
If the answer to both of these is no, that I would pose that these two methods probably shouldn't be overloads in the first place.
If the answer is yes, then you can make only one of these methods abstract:
public abstract class SpaceshipManager : MonoBehaviour
{
public abstract void BuildWith(ParseObject po);
public void BuildWith(string label)
{
// Static method or constructor here to represent label as a ParseObject.
BuildWith(ParseObject.FromLabel(label))
}
}
In this example, ParseObject is the common abstraction. It could also be another class or interface however.
Depending on the situation, the generics option that #Lee posted could also be a good solution, perhaps combined with a non-generic base type:
abstract class SpaceshipManager<T> : SpaceshipManager
{
public abstract void BuildWith(T source);
}
abstract class SpaceshipManager
{
// Other methods here
}
If neither of these solutions work for you, you could always make the method(s) virtual instead and override the behavior if needed, but it's somewhat doubtful that this design makes sense in your situation.

You can implement two Interfaces. IBuildWithFromString and IBuildWithFromParseObject. Then you can query which Interface is implemented by trying to cast to this Interface and in case of successand you can call the appropriate method.

Related

C# 8 default interface implementation and inheritance

I want to use C# 8 default interface implementation to face a performance issue in my code.
Actually, I have this intefaces :
public interface IDataAdapter {}
public interface IDataAdapter<T> : IDataAdapter
{
void Insert(T value);
}
I actually have to do reflection across all IDataAdapter, check generic type and call Insert by reflection for a specific T instance. What I wish to do is :
public interface IDataAdapter
{
void InsertValue(object value);
}
public interface IDataAdapter<T> : IDataAdapter
{
void Insert(T value);
public void InsertValue(object value) => Insert(value as T);
}
The compiler says to use the keyword new to mask the inherited method. However, the only thing I'm trying to accomplish is to have a non-generic method already implemented to make all IDataAdapter<T> implementations to only have to implement the generic version.
Is this something I can accomplish or it's still impossible ? I already know that using an abstract class is a way to solve this issue, but I want to allow a developper to have a class that implements many IDataAdapter...
This is my current reflection code :
public IEnumerable<IDataAdapter> DataAdapters { get; }
public Repository(IEnumerable<IDataAdapter> dataAdapters)
{
DataAdapters = dataAdapters;
}
public async Task SaveAsync()
{
foreach (var item in aggregates)
{
foreach (var dataAdapter in DataAdapters)
{
if (dataAdapter.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericArguments()[0] == item.GetType()))
{
dataAdapter.GetType().GetMethod("Insert", new[] { item.GetType() }).Invoke(dataAdapter, new[] { item });
}
}
}
}
From an object oriented point of view, what you are trying to do can't be done.
Suppose you create the following class hierarchy:
public interface IFoo{}
public interface IBar{}
public class A: IFoo{}
public class B: IFoo{}
public class C:IFoo,IBar {}
And then the following adapters:
public class TestA : IDataAdapter<A>{}
public class TestB : IDataAdapter<B>{}
public class TestC : IDataAdapter<C>{}
public class TestIFoo : IDataAdapter<IFoo>{}
public class TestIBar : IDataAdapter<IBar>{}
public class TestIBoth : IDataAdapter<IFoo>,IDataAdapter<IBar>{}
What should happen if TestA receive an instance of A is quite easy. But what about TestIFoo receive a C? Currently your reflection code won't work because you test type equality (does C equals IFoo? No! Even if C as IFoo is ok).
This breaks Liskov substitution principle. If something works with a class then it should also work with any of its subclasses.
Let's suppose you fix above point. Now what about TestIBoth receiving a C? Is there two different implementation of Insert in it? Of course, this is required by inheritence! But then... do you have to insert C twice? Or do you have to insert it just once in the first fitting method?
The reason why you have to go through reflection is because all those questions needs an algorithmic answer. Your compiler won't be able to answer (which makes the language prevent it by the way)
In the end I would strongly recommend to use a very different solution (like the one proposed by Wim Coenen)
I recognize this problem where you need to look up the IDataAdapter implementation which knows how to handle a certain type of item. I've done something similar for a "view plugin" system, where I would look for the view plugin that knows how to render a certain type. This is useful if you can't know in advance what type of objects you'll need to render.
As far as I know, trying to shoehorn more compile-time type safety into this pattern won't really work, or if it does then it won't actually provide any benefits. I would just declare IDataAdapter like this:
public interface IDataAdapter
{
void InsertValue(object value);
Type SupportedType { get; }
}
If a data adapter supports multiple types, you can make it IEnumerable<Type> SupportedTypes instead, or maybe replace the property by a bool SupportsType(Type) method.

Is this the correct way to use a inheritence?

I'm sorry if these types of questions aren't allowed.
I have a simple base for something similar to plugins.
Here's my example
class Plugin{
private bool _Enabled;
public bool Enabled{
get{
return _Enabled;
}
set{
_Enabled = value;
if(value)
MyExecutionHandler += Run;
}
}
public virtual void Run(object source, System.EventArgs args)
{
if(!Enabled)
return;
}
}
Now currently I'm doing something like this:
class CustomPlugin : Plugin{
public override void Run(object source, System.EventArgs args)
{
base.Run(source, args);
}
}
First of all is the logic behind this correct?
Secondly can I force them to implement the Run function from the partial class or do I need to create an interface for that?
You can define an abstract class with "default" behavior by declaring a method as virtual and overriding it in derived classes.
A derived class is not forced to override a virtual method in an abstract base class. If the method is not overridden, the behavior defined in the abstract class is used. Overriding the method can be used to replace the behavior entirely, or implement additional functionality (on top of calling base.MethodName()).
Unless I've misunderstood your question, this pattern should work for your scenario.
dotnetfiddle link: https://dotnetfiddle.net/7JQQ6I
Abstract base class:
public abstract class Plugin
{
public virtual string Output()
{
return "Default";
}
}
A derived class that uses the default implementation, and one that overrides it:
public class BoringPlugin : Plugin
{
public override string Output()
{
return base.Output();
}
}
public class ExcitingPlugin : Plugin
{
public override string Output()
{
return "No boring defaults here!";
}
}
Test result:
public static void Main()
{
var boring = new BoringPlugin();
Console.WriteLine(boring.Output());
var exciting = new ExcitingPlugin();
Console.WriteLine(exciting.Output());
}
Default
No boring defaults here!
This is not the correct way to use the partial keyword. The partial keyword merely allows you to spread the definition of a class into multiple source files. It isn't something you use to describe the architecture of your program. You would use it to split the definition into multiple files, something like this:
Plugin1.cs
partial class Plugin{
private bool _Enabled;
public bool Enabled{
get{
return _Enabled;
}
set{
_Enabled = value;
if(value)
MyExecutionHandler += Run;
}
}
}
Plugin2.cs
partial class Plugin {
public virtual void Run(object source, System.EventArgs args)
{
if(!Enabled)
return;
}
}
But this isn't helpful to you, and you should forget about the partial keyword (for now). You seem to be struggling with concepts related to object-oriented programming. The partial keyword has nothing to do with that, so don't worry about it.
If you want classes which inherit from Plugin to be 'forced' to implement the Run method, you should use an abstract method. HOWEVER, as you will read in that link, if you use an abstract method, you will not be able to define the 'default' behavior which you are currently defining in the body of the run method.
If you want classes which inherit from Plugin to be forced to define ADDITIONAL behavior, you can't really do that easily just using concepts like abstract classes / methods / interfaces. You will find it easier to compromise, and allow classes which inherit from plugin to 'just' have the default behavior of the Run method as described in your Plugin base class.
You will probably find this compromise acceptable. I think you will find that forcing classes which inherit from Plugin to do additional things in the Run method doesn't buy you anything. The behavior in the base Run method should still be considered a 'correct', if minimal / useless 'Run' of any type of derived Plugin.
I can't speak to the logic of your program, it isn't clear what you intend for these Plugins to do, but hopefully this will help you figure out exactly what you want to do, and how to do it.

What's the difference between an abstract class, and a class with only protected constructors? (.NET)

What are all the difference between an abstract class, and a class with only protected constructor(s)? They seem to be pretty similar to me, in that you can't instantiate either one.
EDIT:
How would you create an instance in a derived class, with a base class with a protected constructor? For instance:
public class ProtectedConstructor
{
protected ProtectedConstructor()
{
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor(); // this is fine
}
}
public class DerivedClass : ProtectedConstructor
{
public void createInstance()
{
ProtectedConstructor p = new ProtectedConstructor(); // doesn't compile
}
public static ProtectedConstructor getInstance()
{
return new ProtectedConstructor(); // doesn't compile
}
}
You can instantiate a class with protected constructors from within the class itself - in a static constructor or static method. This can be used to implement a singleton, or a factory-type thing.
An abstract class cannot be instantiated at all - the intent is that one or more child classes will complete the implementation, and those classes will get instantiated
Edit:
if you call ProtectedConstructor.GetInstance(); instead of new ProtectedConstructor();, it works. Maybe protected constructors can't be called this way? But protected methods certainly can.
Here is an interesting article on the topic.
Most of the time, there is little practical difference, as both are only able to be generated via a subclass.
However, marking a class abstract has two benefits:
With protected constructors, it's still possible to create an instance of the class in two ways. You can use Activator.CreateInstance with BindingFlags.NonPublic, or you can use a factory method defined in the class (or a subclass) to create an instance of the class. A class marked abstract, however, cannot be created.
You are making your intention more clear by marking the class abstract. Personally, I find this the most compelling reason to do so.
From an outside , black-box perspective, yes they are similar in that you cannot instantiate either one. However, you can never instantiate an abstract class, where you can construct a class with only protected constructors from within the class itself, or from an inheritor.
An abstract class can have abstract methods; methods that consist only of the method signature, but no body, that child classes must implement.
Seriously, not one person mentioned that yet?
Your example is flawed because in the getInstance case because you construct a ProtectedConstructor class and expect to down cast it as a DerivedClass. Instead you need a slightly more complete implementation where the derived class has a constrcutor:
public class ProtectedConstructor
{
protected ProtectedConstructor(string arg)
{
// do something with arg
}
public static ProtectedConstructor GetInstance()
{
return new ProtectedConstructor("test");
}
}
public class DerivedClass : ProtectedConstructor
{
protected DerivedClass(string arg) : base(arg)
{
}
public void createInstance()
{
DerivedClass p = new DerivedClass("test");
}
public static DerivedClass getInstance()
{
return new DerivedClass("test");
}
}
Regardless the major difference usage of abstract classes is to define abstract methods that subclasses must implement but you don't want to provide a default implementation for. For example suppose you have some kind of Thread class that has a Run method. You want to ensure that every call to Run first setups up some logging then does the real work of the thread and then stops logging. You could write an abstract Thread class like this:
public abstract Thread
{
protected Thread()
{
}
public void Run()
{
LogStart();
DoRun();
LogEnd();
}
protected abstract DoRun();
private void LogStart()
{
Console.Write("Starting Thread Run");
}
private void LogEnd()
{
Console.Write("Ending Thread Run");
}
}
public class HelloWorldThread : Thread
{
public HelloWorldThread()
{
}
protected override DoRun()
{
Console.Write("Hello World");
}
}
Another thing to consider, that I didn't see other people mention, is that your code may be maintained in the future. If the maintainer adds a public constructor to a class, then it can be instantiated. This might break your design, so you should prevent it (or design to accommodate it).
To prevent other people from making these kinds of changes, you can comment your code. Or, as other people said, use "abstract" to explicitly document your intent.
Well, the first difference that comes to mind is that an abstract class can not be instantiated, but a class with protected constructors could be instantiated throw another public method.
A common example of this might be something like the Singleton pattern: http://en.wikipedia.org/wiki/Singleton_pattern
if you inherit an abstract class from another abstract class, you do not have to satisfy abstract methods, but you do with a normal class with protected ctors. Examples
public abstract class Parent
{
protected abstract void AMethod();
}
public abstract class Child: Parent
{
// does not implement AMethod, and that's ok
}
public class Child2: Parent
{
// does not implement AMethod, and that will cause a compile error
}
If your intent is to only allow static uses of the class (i.e. not to use it as a pure base class) then you should use the static keyword instead; the CLR will prevent instances of the class being created via any method including Reflection (AFAIK).

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

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.";
}
}
}
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)
It appears you have already figured out virtual and override from your example, so:
'abstract' can also be applied on members instead of 'virtual', in which case you do not specify an implementation for the method (';' directly after the signature). This forces all concrete descendants to implement the method.
'new' has nothing to do with inheritance, but can instead be used in a descendant class on a member to hide a member in the base class that has the exact same signature.
In a nutshell ;)
Further to the other answers.
Overrride for when you wish to allow child classes to perform their own processing, no processing or even just call the parent class processing for a function. An override or virtual function does not have to be implemented in descendent classes.
Abstract when you don't wish to perform any processing in your base class but want that method to be implemented by any inheriting class. (Best when the inheriting class behaviour can differ drastically). If a class contains nothing but abstract methods then it is effectively an interface type. A function specified as abstract MUST be implemented in the child class (the compiler will throw an error if not).

Generics, Inheritance and the new operator

Here is something that I find myself using from time to time and I just wanted to get some feedback on the merits of the practice.
Lets say that I have a base class:
abstract class RealBase {
protected RealBase(object arg) {
Arg = arg;
}
public object Arg { get; private set; }
public abstract void DoThatThingYouDo();
}
I often create a second base class that is generic that handles the cast from the "object" type in the base class to the "T" type, like this:
abstract class GenericBase<T> : RealBase {
protected GenericBase(T arg)
: base( arg ) {
}
new public T Arg { get { return (T) base.Arg; } }
}
This allows me to access "Arg" as its explicit type without a cast operation:
class Concrete : GenericBase<string> {
public Concrete( string arg )
: base( arg ) {
}
public override void DoThatThingYouDo() {
// NOTE: Arg is type string. No cast necessary.
char[] chars = Arg.ToLowerInvariant().ToCharArray();
// Blah( blah, blah );
// [...]
}
}
All the while being able to also work with it via the "RealBase":
class Usage {
public void UseIt() {
RealBase rb = new Concrete( "The String Arg" );
DoTheThing(rb);
}
private void DoTheThing(RealBase thingDoer) {
rb.DoThatThingYouDo();
}
}
It is assumed that there are many other "Concrete" types... not just the one.
Here are my questions/concerns:
Am I "off my rocker" for using
an approach like this?
Are there
any obvious drawbacks/caveats to
using this approach?
What about
that "new public T..." in
GenericBase? Good/bad idea? Awkward?
Any feedback or advice would be greatly appreciated.
I don't have any objection to that explicitly as long as you're disciplined enough to only use the generic base class as a helper only and never downcast to it. If you start referencing RealBase and GenericBase and ConcreteClass all over the place things tend to get real tightly coupled really quickly.
As a matter of fact, I would recommend kicking it up a notch and introducing an interface
interface IReal {
void DoThatThingYouDo();
}
And leaving the base class out of it entirely (basically never reference it except when declaring a derived class). Just a tip that helps me increase the flexibility of my code.
Oh, and if you do use an interface, don't just declare it in the base classes, declare it on the concrete ones:
class MyConcrete: BaseClass<MyConcrete>, IReal {
...
}
as a reminder, the base class is not important only what it does is important!
Well, we've now got an inheritance tree three levels deep, but you haven't given any particular reason for doing this.
Personally I rarely use inheritance (or rather, rarely design my own inheritance hierarchies beyond implementing interfaces and deriving directly from object). Inheritance is a powerful tool, but one which is difficult to use effectively.
If this gives you some clear advantage over other approaches, that's fine - but I would consider the complexity you're adding for someone reading the code. Do they really want to have to consider three levels of hierarchy, with two properties of the same name? (I would rename GenericBase.Arg to GenericBase.GenericArg or something like that.)
I think you would be able to get the same functionality you would like by using an interface as opposed to dual abstract base classes, consider this:
public interface IAmReal
{
void DoThatThingYouDo();
...
}
abstract class GenericBase<T> : IAmReal
{
protected GenericBase<T>(T arg)
{
Arg = arg;
}
public T Arg { get; set; }
public abstract void DoThatThingYouDo();
}
class MyConcrete : GenericBase<string>
{
public MyConcrete(string s) : base(s) {}
public override void DoThatThingYouDo()
{
char[] chars = Arg.ToLowerInvariant().ToCharArray();
...
}
}
class Usage
{
public void UseIt()
{
IAmReal rb = new MyConcrete( "The String Arg" );
DoTheThing(rb);
}
private void DoTheThing(IAmReal thingDoer)
{
rb.DoThatThingYouDo();
}
}
I don't think you're off your rocker. See Curiously Recurring Template for something even more complex.
Personally I would strongly advise not to use the new operator, since it may lead to confusion. Actually I myself have recently had such a problem, but I went with base class abstract suffixed with AsObject, i.e.:
public BaseClass{
public abstract object ValueAsObject {get;set;}
}
and generic class along the line:
public BaseClass<T> : BaseClass {
public T Value {get;set;}
public override object ValueAsObject {
get{return (T)this.Value;}
set{this.Value = value;} // or conversion, e.g. string -> int
}
Georg Mauer's proposal of interface for DoThatThingYouDo is also good.
Am I the only one who thinks inheritance should be avoided as far as it can? I've seen different implementations when inheritance have caused bizarre problems, not only when trying to downcast. Interfaces are the savior! I'm not saying that inheritance should always be avoided, but by just looking at the specified code I can't see the advantages of this inheritance tree over regular interfaces.

Categories

Resources