How to instantiate an extended class with a different base implementation? - c#

I'm working with a binary that contains an object and the base class it extends. I want to instantiate the object, but for it to use my own implementation of the base class. I can see in the base class to know what methods I need t extend.
The problem is that the base class implements a method called "WriteFeed" that expects network connections and writes data out to a network stream. I would like it to use my implementation so WriteFeed can instead dump data to console.
I cannot change the existing binaries, only the way I consume and instantiate it.

My only suggestion is to use a composite approach. I'm not sure if this will meet your need or you have visibility access, but it may work.
public class SomeBaseClassInSomeBinary
{
protected virtual void Method1(...) {}
protected virtual void WriteFeed (...) {}
}
public class SomeClassInSomeBinary: SomeBaseClassInSomeBinary
{
protected override void Method1(...) { base.Method1(...); }
protected override void WriteFeed (...) { base.WriteFeed (...); }
}
// **** your code
public class MyCode: SomeBaseClassInSomeBinary
{
private SomeClassInSomeBinary Composite = new SomeClassInSomeBinary();
protected override void Method1(...) { Composite.Method1(...); }
protected override void WriteFeed (...) { your implementation }
}
}
All you need to do is now use your object instead.
Hope this helps.

Related

Adjust accessibility of derived methods when changed on parent

I decided to change access modifier of a method which is overridden in multiple classes. So now I need to adjust accessibility modifier in all of them.
I assumed that is so common operation that Visual Studio (2019) should be able to do it automatically for me, but I couldn't find a way to do it.
Did I miss something or "manually" is the only way to go?
Not available out of the box.
Find and replace could mostly work:
Find in project/solution: public override void MyMethod(
Replace with: 'protected override void MyMethod('
Roslynator is a free/open source Visual Studio extension that has a large amount of extra refactorings, a.o. change accessibility.
For example, this changes this:
class Base
{
protected virtual void Method() { }
}
class Derived : Base
{
protected override void Method() { }
}
to this:
class Base
{
public virtual void Method() { }
}
class Derived : Base
{
public override void Method() { }
}
You could click on the x references tag above the class name to get a list of derived classes:

Limit inheritance of intermediate abstract class

I have an abstract class, CreatureBehaviour, that provides a TakeTurn method. The goal of this is to decide what the creature should do, and it should provide its response via callback. This is because the response may require player input, so it shouldn't block other processes.
public abstract class CreatureBehaviour {
public abstract void TakeTurn (Action<TurnAction> response);
}
Inheriting from this, the PlayerControl class stores the response callback for later decision-making. Most of its content isn't relevant, but ultimately it must invoke response when the player does something.
public class PlayerControl : CreatureBehaviour {
Action<TurnAction> responseCallback;
public override void TakeTurn(Action<TurnAction> response) {
responseCallback = response;
}
// Various UI callbacks that can send something to "responseCallback" when appropriate.
}
And all non-player creatures need to be able to send a callback too. For safety, I want to ensure that a callback is always hit, so I've created an abstract NonPlayerControl class that ensures a response:
public abstract class NonPlayerControl : CreatureBehaviour {
protected abstract TurnAction TurnResponse ();
public override void TakeTurn (Action<TurnAction> response) {
response (TurnResponse ());
}
}
With this, all of my non-player creature behaviours can derive from NonPlayerControl and simply implement TurnReponse(). The compiler guarantees that all their scripts will return a response, rather than leaving the callback hanging. Note that PlayerControl can't implement TurnResponse() because it would need to guarantee an immediate return, and that would block other processes.
So I want to derive other classes from NonPlayerControl and maybe from PlayerControl, but I don't want to accidentally derive another class from CreatureBehaviour and risk missing the callback.
Is there any way I can "sort of seal" CreatureBehaviour so that it can only have these two direct children and prevent any others? If not, is there a better pattern I could be using here?
There's nothing you could do for this in a "normal" way, but there's one option you could consider...
If you give your CreatureBehavior class just a private constructor, then nest PlayerBehavior and NonPlayerBehavior within that class, they will have access to the private constructor but no other classes will... so no other classes could derive from CreatureBehavior.
A simpler solution would be to:
Document in CreatureBehavior that it shouldn't be subclassed directly
Write unit tests to validate that there aren't any other subclasses
That can only test your code rather than code in other assemblies, of course. If you don't need these from other assemblies, then make the classes internal instead of public. Even if you need all the classes to be public, you could include a no-op abstract internal method that's implemented in PlayerBehavior and NonPlayerBehavior - that will stop classes outside your assembly from deriving from CreatureBehavior as they can't implement the internal abstract method.
Just a quick idea, without further testing: Could you use a generic to do the restriction?
public abstract class CreatureBehaviour<T> where T : IPlayerControl, INonPlayerControl {
// ...
}
And then use it in the following way:
public abstract class NonPlayerControl : CreatureBehaviour<NonPlayerControl>, INonPlayerControl {
// ...
}
public abstract class PlayerControl : CreatureBehaviour<PlayerControl>, IPlayerControl {
// ...
}
It is sort of a hack, but it might work for your case.
You cannot prohibit inheritance from the CreatureBehavoiur class but you can limit access to TakeTurn methods by combining internal, sealed and protected access and place it in the separate assembly:
public abstract class CreatureBehaviour
{
protected abstract void TakeTurn(Action<TurnAction> response);
}
public class PlayerControl : CreatureBehaviour
{
private Action<TurnAction> responseCallback;
protected override void TakeTurn(Action<TurnAction> response)
{
responseCallback = response;
}
internal void TurnByPlayer(Action<TurnAction> response)
{
TakeTurn(response);
}
// Various UI callbacks that can send something to "responseCallback" when appropriate.
}
public abstract class NonPlayerControl : CreatureBehaviour
{
protected abstract TurnAction TurnResponse();
protected override void TakeTurn(Action<TurnAction> response)
{
response(TurnResponse());
}
internal void TurnByNonPlayer(Action<TurnAction> response)
{
TakeTurn(response);
}
}
public sealed class CreatureStearing
{
public void Turn(PlayerControl control)
{
control.TurnByPlayer((action) => {});
}
public void Turn(NonPlayerControl control)
{
control.TurnByNonPlayer(action => {});
}
}
Now you can inherit from PlayerControl, NonPlayerControl, and even CreatureBehaviour in other assemblies, but you cannot use TakeTurn methods for any class intances other than PlayerControl and NonPlayerControl that are in separate assemblies:
public class SomeTest1 : PlayerControl
{
protected override void TakeTurn(Action<TurnAction> response)
{
base.TakeTurn(response);
}
}
public class SomeTest2 : NonPlayerControl
{
protected override TurnAction TurnResponse()
{
throw new NotImplementedException();
}
protected override void TakeTurn(Action<TurnAction> response)
{
base.TakeTurn(response);
}
}
public class SomeTest3 : CreatureBehaviour
{
protected override void TakeTurn(Action<TurnAction> response)
{
throw new NotImplementedException();
}
}
....
var t1 = new SomeTest1();
var t2 = new SomeTest2();
var t3 = new SomeTest3();
var creatureStearing = new CreatureStearing();
creatureStearing.Turn(t1);
creatureStearing.Turn(t2);
creatureStearing.Turn(t3); // 'Cannot resolve method 'compile error here
Of course you can pass this limitation by declaring internal access for your assembly, but it requires to implement something like CreatureStearing (well some efforts) but other party in this case will know for sure this is a hack.

c# inheritance of base class to template

I want to write a framework which needs to implement a few functions. Now I need to access the base class functions from the framework, which does not work.
I need to inherit form a given class "Master"
public class MyClass : Master
{
protected override void Initialize() {
FunctionInMaster();
VariableInMaster = true;
}
}
Now I simply want to create a class that can be derived and implements Master functions.
public class MyFrameworkClass
{
// framework override
public void whatever()
{
FunctionInMaster();
VariableInMaster = true;
}
}
public class MyClass : Master
{
protected override void Initialize() {
whatever();
FunctionInMaster();
VariableInMaster = true;
}
}
How do I do that without instantiating "MyFrameworkClass" and passing a pointer of "this" to MyFrameworkClass?
You can never have multiple inheritance in C# (and it's a very good thing, multiple inheritance is a nightmare), but you can invoke methods from other classes, or even have some composition.
public static class MyFrameworkClass
{
// framework override
public static void whatever(Master master)
{
master.FunctionInMaster();
master.VariableInMaster = true;
}
}
public class MyClass : Master
{
protected override void Initialize()
{
MyFrameWorkClass.whatever(this);
FunctionInMaster();
VariableInMaster = true;
}
}
Don't try to do too many things with inheritance. Inheritance is a powerful tool, but not an universal one. Often composition is better suited to tackle a specific problem.
You could also have multiple levels of inheritance, if you need to access protected methods and you know you will reuse this code in other derived classes.
public class MyFrameworkClass : Master
{
// framework override
protected void whatever()
{
FunctionInMaster();
VariableInMaster = true;
}
}
public class MyClass : MyFrameworkClass
{
protected override void Initialize()
{
whatever();
FunctionInMaster();
VariableInMaster = true;
}
}
Although you could change inheritance to be Master -> MyFrameworks -> MyClass, that is less advisable. Is the intention to make sure deriving classes implement specific methods - in that case consider adding abstract methods to Master. If you are unable to alter Master, you can change MyFrameworks to be an interface rather than a class. MyClass can inherit multiple interfaces, but only one class.
I need to access the base class [instance] functions from the framework
To call instance methods you need an instance. There are three ways to do that:
Inherit form the class and use this - you have already stated that you can't do this.
Accept an instance of the base class and call methods on it - you have stated that you don't want to do this.
Create an instance of the class and call methods on it.
Now static methods are different - you do not need an instance, but they can only use static fields, which would be shared across all instances of the class. Since you use a non-static property in the base class, it's safe to assume that static is not an option, so you're stuck with one of the three options above.

Order of execution in Abstract Class

I came across a posting where it is said that MustBeCalled() method will get called if we have the Abstract class do the calling in this manner.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
}
//could also be public if desired
protected abstract void AbstractMethod();
}
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
}
}
But how does MustBeCalled() method get called?
In what order things are called here?
If you call PerformFunction() first, then everything will execute in the intended order, where that order is specified in the order of the lines of code in PerformFunction(). If you call AbstractMethod() directly, there's no guarantee that MustBeCalled() will ever be called. However, I notice that you have AbstractMethod() marked as protected, which means that outside consumers of your class will not be able to call it directly. They'll have to use PerformFunction() -- this is good, as there is now only one public way to invoke your internal methods, and that way guarantees the order that you need.
In truth, there is a level at which you can only guarantee that things happen by choosing to write code to make them happen. You can't, for example, guarantee that code is going to implement a game of Tetris except by actually writing that code and choosing to implement it in such a way that it produces Tetris behavior. The type system and the public/protected/private modifiers can help some by preventing some misuse (as your internals are not accessible and thus cannot be invoked by consumers of your module), but they can only go so far. This is such a case.
You cannot enforce how an implementation to call a method when invoked. The implementation could do its own thing entirely, or do nothing.
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
// this is a perfectly valid implementation
}
}
A better implementation could be.
public abstract class AbstractClass
{
public void PerformThisFunction()
{
MustBeCalled();
AbstractMethod();
}
private void MustBeCalled()
{
}
protected virtual void AbstractMethod()
{
MustBeCalled();
}
}
This way refactoring tools will at least create the desired boilerplate code:
public class ImplementClass : AbstractClass
{
protected override void AbstractMethod()
{
base.AbstractMethod();
}
}
However, the person overriding AbstractMethod still needs to call base.AbstractMethod, this is not enforced by the compiler at all.

C# Overriding abstract methods (include input parameters)

It is possible in C# do something like this
public absctract class ImportBase()
{
public abstract void CreateDocument();
}
public class UsingOne : ImportBase
{
public override bool CreateDocument(string name)
{
return null;
}
}
I want have some Base class, which only have some methods,but in derived class i need change inputs parameters and inside of method.
You're not overriding the method. The point of having an abstract (or virtual) method is that given any ImportBase, I should be able to call
importBase.CreateDocument();
That's clearly not the case with UsingOne, as it needs more information. So you're really trying to tie your caller to UsingOne, not just ImportBase - at which point you've lost the benefits of polymorphism.
To override a method, the implementation has to have the same signature, basically.
Probably you want to minimize the duplicate code on your derived classes. Basically it's not possible to have an override of a different signature but surely you can refactor your code where you can keep the possible duplicate code in the base class and use it on your derived classes.
public absctract class ImportBase()
{
//Making this protected here
protected virtual void CreateDocument()
{
//Your CreateDocument code
};
}
public class UsingOne : ImportBase
{
private override void CreateDocument()
{
// Override this if you have different CreateDocument for your different
// for different derived class.
}
public bool CreateDocument(string name)
{
// Do whatever you need to do with name parameter.
base.CreateDocument();
// Do whatever you need to do with name parameter.
return true; // return false;
}
}
You can create instance of UsingOne and invoke CreateDocument(string name)
nope. signature must be same on the derived class. i suggest to use builder pattern.
http://en.wikipedia.org/wiki/Builder_pattern

Categories

Resources