How to use Activator.CreateInstance() to call an override C# - c#

I am looking to find the proper way to call a overridden function of an inherited class using the Activator.CreateInstance() function. I am doing this so that I can call a specific function of a derived class based on a string object, such that the string determines which derived class object will be created and have its function called. Something like this but I do not know how to do it properly or if there is a better way than using Activator.
public class Test
{
public virtual void DefaultCalibration()
{
//Do nothing
}
}
public class EasyTest : Test
{
public override void DefaultCalibration()
{
//Do one thing
}
}
public class HardTest : Test
{
public override void DefaultCalibration()
{
//Do another thing
}
}
public class Tester
{
public void main()
{
string testName = "";
// ...
// ... Do some stuff to get a string of the name of the class, ie testName = "HardTest";
// ...
Type type = Type.GetType(testName);
object instance = Activator.CreateInstance(type);
((Test)instance).DefaultCalibration(); //this line doesn't call the derived function
}
}
I want it so that the derived class' override function is called instead of the base class function.
The intent being that if my string is "HardTest", then it would essentially look like
((HardTest)instance).DefaultCalibration();
but if it was "EasyTest" then it would look like
((EasyTest)instance).DefaultCalibration();

Related

Accessing a private method in a overridden public method

I am currently having some issues with accessing a private method from a overriden public method.
My situation is like this: I have a compiled .dll file which consist basically of this
public class OriginalHandler
{
public virtual void Request()
{
RedirectIfConditionIsFulfilled()
this.PeformRequest()
}
protected virtual bool PeformRequest()
{
}
private static void RedirectIfConditionIsFulfilled()
{
}
}
I need to alter the method PeformRequest(), So i make a public class, which inherit OriginalHandler and override the method as such:
public class ModifiedOriginalHandler : OriginalHandler
{
protected override bool PeformRequest()
{
}
}
To ensure that this method doesn't violate an "impact" scope, I have to ensure that it only get evaluated on certain sites,
We use this to ensure that HttpRequestProcess ONLY impact the desired site using this
namespace Sitecore.Sharedsource.Pipelines.HttpRequest
{
using System.Collections.Generic;
using Assert = Sitecore.Diagnostics.Assert;
using S = Sitecore;
public abstract class SiteSpecificHttpRequestProcessor: S.Pipelines.HttpRequest.HttpRequestProcessor
{
public abstract List<string> _sites;
public sealed override void Process(S.Pipelines.HttpRequest.HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (S.Context.Site == null || !this._sites.FirstOrDefault(S.Context.Site.Name))
{
return;
}
this.DoProcess(args, this._sites.FirstOrDefault(S.Context.Site.Name));
}
protected abstract void DoProcess(S.Pipelines.HttpRequest.HttpRequestArgs args, string);
}
}
So include my ModifiedOriginalHandler to include this
public class SiteSpecificModifiedOriginalHandler: SiteSpecificHttpRequestProcessor
{
Public override List<String> _sites => new[]
{
"www.only.com" , "www.boat.com"
};
public virtual HttpContext GetHttpContext()
{
return HttpContext.Current;
}
public override void DoProcess(HttpRequestArgs args, string)
{
var mediaRequest = new ModifiedOriginalHandler ();
var context = GetHttpContext();
var site = Sitecore.Context.Site;
if (site == null)
{
return;
}
if (string != null)
{
mediaRequest.Request(context);
}
else
{
OriginalHandler baseClass = mediaRequest;
baseClass.Request(context);
}
}
}
This Is where I am having a problem, I can from the SiteSpecificModifiedOriginalHandler not call the protected method PeformRequest,
but can call the public method Request which internally calls the desired function, so I make an override function,
to ensure that the original is not being called but my modified version
public class ModifiedOriginalHandler : OriginalHandler
{
protected override bool PeformRequest()
{
}
public override void Request()
{
RedirectIfConditionIsFulfilled()
this.PeformRequest()
}
}
Which is where I am having my problem, RedirectIfConditionIsFulfilled is a private method,
and I can in no way make this method call as such. I could in my overridden function remove this call, but that would
require RedirectIfConditionIsFulfilled to be removed, which would alter the original functionality, which i don't want to do.
So how do i overcome this?
How do i access a private method in a overriden public method?
If you have access to OriginalHandler implementation then make the derived class a nested one:
class A {
private void Foo() { }
protected virtual void Bar() { }
public class B: A {
protected override void Bar() {
Foo(); \\ legal } } }
If you don’t then barring reflection there is no way to access from an external type a private member of another type.
You can't access a private method from an inherited class. (But you know that.)
But your question didn't give any reason why your method shouldn't be protected, which would expose it to inherited classes.
What you're describing is exactly why protected exists.
A nested class will work, but I don't recommend it unless you want every single inherited class that needs the private method to be nested inside the base class. What if some of those inherited classes have their own private methods and even more inherited classes need to access those? You'd have to nest classes inside your nested classes.

RhinoMock - mocking multiple stubs for the same class

Say I have a class that is being called from within my MainClass method that I am testing.
public class MainClass
{
private readonly SubClass;
// constructor not shown
public method TestMethod()
{
var data = SubClass.MethodA();
// ...some code
var moreData = SubClass.MethodB(someOtherData);
// ...more code
}
}
Using RhinoMock, I'd like to create a stub for SubClass.MethodA() to return a specified set of data in the test, however when calling SubClass.MethodB(), I want to call the original implementation.
I wouldn't want to break out the SubClass' two methods out into their own classes as they fit in SubClass. Is there a way in RhinoMock to stub out one method while calling another method in the same class (that is not a stub)?
I would use the extract and override test pattern and a simple stub for this.
This doesn't explicitly use Rhino though but will do for your scenario.
If you don't want to go down this path consider injecting Subclass into MainClass via a constuctor, public setter or parameter, and then you can have more control of mocking subclass first.
The idea is to make a virtual method that a sub class stub can override to take control of the behaviour of a part of a class under test.
public class MainClass
{
private readonly SubClass _subClass;
// constructor not shown
public void TestMethod()
{
var data = SubClassMethodACall();
// ...some code
var someOtherData = "";
var moreData = _subClass.MethodB(someOtherData);
// ...more code
}
protected virtual string SubClassMethodACall()
{
return _subClass.MethodA();
}
}
public class SubClass
{
public string MethodA()
{
return null;
}
public string MethodB(string s)
{
return null;
}
}
namespace Tests.Unit
{
public class MainClassStub : MainClass
{
private readonly string _returnValueForMethodA;
public MainClassStub(string returnValueForMethodA)
{
_returnValueForMethodA = returnValueForMethodA;
}
protected override string SubClassMethodACall()
{
return _returnValueForMethodA;
}
}
[TestFixture]
public class TestClass
{
[Test]
public void TestMethod()
{
var mainClass = new MainClassStub("this is the test value returned");
//.. rest of test
}
}
}

How can I assign a new action to an existing method?

I've created a class in C# which uses the method "Action".
public void Action()
{
}
The method is empty because, when a new instance of the class is created, the user should be able to define what the method does. One user may need the method to write to the console, another may want it to assign a value to a variable, etc. Is there any way for me to change what the method can do outside of its original definition, along the lines of the following:
//Using the instance "MyClass1", I have assigned a new action to it (Writing to the console)
//Now the method will write to the console when it is called
MyClass1.Action() = (Console.WriteLine("Action"));
Is there any way for me to change what the method can do outside of
its original definition
Not via "Named Methods" and the way you're using them in your example. If you want your class to be able to invoke a unit of execution defined by the user, you need to look either into inheritance hierarchy (as specified in #CodeCaster answer via virtual methods and overriding them), or perhaps look into delegates.
You can use an Action delegate:
public Action Action { get; set; }
Use it like so:
var class = new Class();
class.Action = () => { /*Code*/ }
And, when you want to invoke it:
if (class.Action != null)
{
class.Action();
}
By making it abstract, inheriting the class and overriding the method.
public class FooBase
{
public abstract void Bar();
}
public class Foo1 : FooBase
{
public override void Bar()
{
// Do something
}
}
public class Foo2 : FooBase
{
public override void Bar()
{
// Do something else
}
}

Can you add a Derived Class to a list of its base class then call a method of the Derived class from the list of base class in C#

Can you add a Derived Class to a list of its base class then call a method of the Derived class from the list of base class(possibly by casting it back to the Derived class since you know it was originally a Derived class)
public class MySystem
{
public string name;
MySystem(string name)
{
this.name = name;
}
public void Update()
{
//dostuff
}
}
public class PowerSystem : MySystem
{
public int totalPower;
PowerSystem (string name, int power) : base(name)
{
this.totalPower = power;
}
public void Update()
{
base.Update();
//Do other stuff
}
}
void Main()
{
List<MySystem> SystemList = new List<MySystem>();
SystemList.Add(new System("Shields"));
SystemList.Add(new System("Hull"));
Power p = new Power("Power", 10);
SystemList.Add(p);
foreach(MainSystems ms in SystemList)
{
if(ms.name != "Power")
ms.Update();
else
(PowerSystem)ms.Update(); //This doesn't work
}
}
So what I'm trying to do is run the update method for every element in the list, with the exeption of the one I named power and instead run the Power.Update method.
The closest post I have found to answering this is here unfortunately I don't fully understand it.
I'm hoping that the list is holding a reference to PowerSystem p and that somehow I can convert it and access the PowerSystem menthod.
I hope this is clear.
Thanks
PS if you have a better idea for this I'm all ears.
Use polymorphism - mark Update in base class virtual and override it in derived class.
Base classes may define and implement virtual methods, and derived
classes can override them, which means they provide their own
definition and implementation. At run-time, when client code calls the
method, the CLR looks up the run-time type of the object, and invokes
that override of the virtual method. Thus in your source code you can
call a method on a base class, and cause a derived class's version of
the method to be executed.
public class MySystem
{
public string name;
MySystem(string name)
{
this.name = name;
}
public virtual void Update()
{
//dostuff
}
}
public class PowerSystem : MySystem
{
public int totalPower;
PowerSystem (string name, int power) : base(name)
{
this.totalPower = power;
}
public override void Update()
{
base.Update();
//Do other stuff
}
}
Now, PowerSystem.Update() will get called automatically
foreach(MainSystems ms in SystemList)
{
ms.Update();
}
For MySystem instances it will call MySystem.Update, but for PowerSystem instances the override will be called.

Best way to share a function between two class files

There are two files A.cs and B.cs. There is a method fn() which is used in both the classes.
Method fn() is used in both class files. This increases code complexity if I need this method in many class files (say 100 files).
I know that we can call this method by creating an object for the class in which this method is defined. How can I share this function between two or more classes without creating an object every time for accessing this method?
Put the method in a static class:
public static class Utils
{
public static string fn()
{
//code...
}
}
You can then call this in A.cs and B.cs without creating a new instance of a class each time:
A foo = new A();
foo.Property = Utils.fn();
Alternatively, you could create a BaseClass that all classes inherit from:
public class BaseClass
{
public BaseClass() { }
public virtual string fn()
{
return "hello world";
}
}
public class A : BaseClass
{
public A() { }
}
You would then call fn() like so:
A foo = new A();
string x = foo.fn();
I hope the function isn't really called fn(), but actually named to what it does, like CalculateTotal(). Then you can extract this method into a class, say: TotalCalculator.
Now upon application startup, preferably using dependency injection, you create one instance of the class that gets shared between objects that require it. Like so:
class TotalCalculator
{
public int Calculate()
{
return 42;
}
}
class NeedsCalculator1
{
TotalCalculator _calculator;
public NeedsCalculator1(TotalCalculator calculator)
{
_calculator = calculator;
}
public void Foo()
{
_calculator.Calculate();
}
}
class NeedsCalculatorToo
{
TotalCalculator _calculator;
public NeedsCalculatorToo(TotalCalculator calculator)
{
_calculator = calculator;
}
public void Bar()
{
_calculator.Calculate();
}
}
Then you instantiate the calculator once, and pass it into the other classes' constructor:
TotalCalculator calculator = new TotalCalculator();
NeedsCalculator1 dependency1 = new NeedsCalculator1(calculator);
NeedsCalculatorToo dependency2 = new NeedsCalculatorToo(calculator);
You can now further abstract the calculator dependency by creating a base class containing the constructor and a protected TotalCalculator instance field, for example.
Assuming that this method is self contained, you could create a static class and put this method as a static method in it, which is in turn, called by the other classes.
If is is not self contained, you could try and declare it in some super class and let the other 100 classes extend that class.

Categories