"override method at runtime" C# - c#

I want to override method Print of a ClassA in a custom dll.
public ClassA
{
public void Print( string arg1, string arg2, string arg3, string arg4 )
{
}
}
Is this possible in C# ?

I believe Moles from Microsoft Research does something similar. They have a system that allows you to override the working of e.g. DateTime.Now, forcing it to return a specific date/time.
Have a look at http://research.microsoft.com/en-us/projects/pex/default.aspx for more information.

This is not quite the same thing as you are asking, but it achieves a similar effect...
Why not define an interface for your operations. ClassA implements the interface. Your custom Strategies also implement the interface. ClassA internally creates the "default" implementation of the interface at startup (when ClassA is instantiated), but also has a property that allows the interface to be set. The interface might even allow the custom Strategy to specify which members of the interface that it actually implements:
interface IStrategy
{
void Operation1(int x, int y);
void Operation2(string a, string b);
}
class ClassA : IStrategy
{
private IStrategy builtInStrategy = new BuiltInStrategy();
public IStrategy CustomStrategy { get; set; }
void Operation1(int x, int y);
{
if (CustomStrategy != null)
{
CustomStrategy.Operation1(x, y);
}
else
{
builtInStrategy.Operation1(x, y);
}
}
void Operation2(string a, string b)
{
if (CustomStrategy != null)
{
CustomStrategy.Operation2(a, b);
}
else
{
builtInStrategy.Operation2(a, b);
}
}
}
You could specify as part of the IStrategy interface a way for the custom Strategy to indicate that it is not "overriding" a particular operation. Perhaps it could return a bool rather than a void or perhaps each operation could have an out bool parameter that is set to false if the custom Strategy has not overridden an operation.
Depending on how many operations can be overridden, you might even consider putting each operation its own interface. Operations could be grouped in an interface if it is not reasonable to implement one operation without also implementing some other operations.
interface IOperation1
{
void Operation1(int x, int y);
}
interface IOperation2
{
void Operation2(string a, string b);
}
interface IMath
{
int Add(int i, int j);
int Subtract(int i, int j);
int Multiply(int i, int j);
int Divide(int i, int j);
}
interface IStrategy
{
//What operations should the Strategy have?
}
class ClassA : IOperation1, IOperation2, IMath
{
public IStrategy CustomStrategy { get; set; }
public void Operation1(int x, int y)
{
IOperation1 op1 = CustomStrategy as IOperation1;
if (op1 != null)
{
op1.Operation1(x, y);
}
else
{
//Do ClassA's Operation1 logic here
}
}
public void Operation2(string a, string b)
{
IOperation2 op2 = CustomStrategy as IOperation2;
if (op2 != null)
{
op2.Operation2(a, b);
}
else
{
//Do ClassA's Operation2 logic here
}
}
//
// And so on ...
//
}

Your first problem: the method is not marked virtual. You cannot override a non-virtual method.
As for the question, it all depends how ClassA is instantiated and used. You could for example create a derived type at runtime, if you can control the instantiation and usage of it.

This is not possible, because i can't extend ClassA because it is in the Core dll delivered with the application

Related

How to call methods of data member through a generic method

Considering the classes below, I would like to be able to write:
B b = new B();
b.f(1); // calls b._a.f(int)
b.f("howdy!"); // calls b._a.f(string)
Class A cannot be modified.
public class A
{
public void f(int i) { }
public void f(string s) { }
}
public class B
{
public void f<T>(T v)
{
_a.f(v); // fails
}
A _a = new A();
}
If you really want to simplify your f pass-through down to a single method, you'll have to use run-time type checking. I don't see any other way around it. Generics aren't going to work here.
public void f(object v)
{
if (v is int i)
_a.f(i);
else if (v is string s)
_a.f(s);
else
throw new InvalidOperationException();
}
I gather that you are hesitant to just expose _a because there are some methods on it that you would rather not be accessible to the caller? Could you introduce an interface, or would that be considered a modification to class A?
public interface IFoo
{
void f(int i);
void f(string s);
}
public class A : IFoo
{
...
}
public class B
{
public IFoo A => _a;
}

How do you change the type of an inherited method?

I want to make a game where I have 3 types of characters, each type has a different attack for each other type. I would like to have an abstract class Character with an abstract method (it's a requirement) and 3 classes that inherit the method and then overload it for each type. The problem is that my attack method in my Character class takes a type Character argument and that I have to overwrite it in my sub classes with an empty method which makes the use of that abstract class and method really useless. So what can I do better than :
public abstract class Character
{
public abstract void Attack(Character t);
}
public class A :Character
{
public override void Attack(Character t){}
public void Attack(A x)
{
/*instructions*/
}
public void Attack(B y)
{
/*instructions*/
}
public void Attack(C z)
{
/*instructions*/
}
}
And so on for class B and C.
I would prefer to avoid that also :
public abstract class Character
{
public abstract void Attack(Character c);
}
public class A :Character
{
public override void Attack(Character t)
{
A x = t as A
if (x != null)
{
/*instructions*/
}
B y = t as B
if (y != null)
{
/*instructions*/
}
C z = t as C
if (z != null)
{
/*instructions*/
}
}
}
I hope my question is clear enough despite my english.
You can implement this dispatch with a little "magic" from dynamic:
abstract class Character {
public void Attack(Character c) {
((dynamic)this).DoAttack((dynamic)c);
}
}
class A : Character {
public void DoAttack(A a) { Console.WriteLine("A attacks A"); }
public void DoAttack(B b) { Console.WriteLine("A attacks B"); }
public void DoAttack(C c) { Console.WriteLine("A attacks C"); }
}
class B : Character {
public void DoAttack(A a) { Console.WriteLine("B attacks A"); }
public void DoAttack(B b) { Console.WriteLine("B attacks B"); }
public void DoAttack(C c) { Console.WriteLine("B attacks C"); }
}
class C : Character {
public void DoAttack(A a) { Console.WriteLine("C attacks A"); }
public void DoAttack(B b) { Console.WriteLine("C attacks B"); }
public void DoAttack(C c) { Console.WriteLine("C attacks C"); }
}
Note the cast of both this and c to dynamic, this is what lets the runtime locate the relevant DoAttack override without relying on inheritance structure.
Demo.
An advantage of this approach is that you can add new implementations as you wish: the rest of the code will continue to work, as long as attacks are limited to pairs of objects of "valid" types.
A disadvantage of this approach is that it is not statically typed, meaning that it would compile even in the absence of a method that handles the desired interaction. You can mitigate this problem by providing a "default" implementation of DoAttack(Character c) in the Character class itself.
If you want to avoid the dynamic dispatch solution dasblinkenlight has presented, you could go about this by implementing the Visitor pattern. We need to add a new method to your abstract class.
public abstract class Character
{
public int HP {get;set;}
public abstract void Attack(Character t);
public abstract void Accept(ICharacterVisitor visitor);
}
As well as create our ICharacterVisitor interface.
public interface ICharacterVisitor {
void Visit(A a);
void Visit(B b);
void Visit(C c);
}
Lets go ahead and define some rules for attacking as character A in the terms of the ICharacterVisitor.
public class AttackVisitorA : ICharacterVisitor
{
private int _baseDamage;
public AttackVisitorA(int baseDamage){
_baseDamage = baseDamage;
}
public void Visit(A a)
{
// A does normal damage to A.
a.HP -= _baseDamage;
}
public void Visit(B b)
{
// A does double damage to B.
b.HP -= (_baseDamage * 2);
}
public void Visit(C c)
{
// A does half damage to C.
c.HP -= (_baseDamage / 2);
}
}
Now we can implement our A, B, and C characters. I've left the implementation of Attack on B and C as an exercise to the reader.
public class A : Character
{
public override void Accept(ICharacterVisitor visitor)
{
visitor.Visit(this);
}
public override void Attack(Character t)
{
var damage = 15;
t.Accept(new AttackVisitorA(damage));
}
}
public class B : Character
{
public override void Accept(ICharacterVisitor visitor)
{
visitor.Visit(this);
}
public override void Attack(Character t)
{
throw new NotImplementedException();
}
}
public class C : Character
{
public override void Accept(ICharacterVisitor visitor)
{
visitor.Visit(this);
}
public override void Attack(Character t)
{
throw new NotImplementedException();
}
}
Now, we can conduct attacks from characters on other characters fairly simply:
void Main()
{
var a = new A { HP = 100 };
var b = new B { HP = 100 };
var c = new C { HP = 100 };
a.Attack(a); // stop hitting yourself
a.Attack(b);
a.Attack(c);
Console.WriteLine(a.HP); // 85
Console.WriteLine(b.HP); // 70
Console.WriteLine(c.HP); // 93
}
The logic is effectively decoupled from your object hierarchy. You can implement a DefaultAttackVisitor that goes through standard rules, or have an AttackVisitor for each character type, or perhaps some more complex rules based on weapons or spells. Either way you've ended up with a fairly clean and easily swapped set of logic for resolving attacks between classes.
Implementing visitor over using Dynamic Dispatch will lend you a bit more compile-time type safety. If at some point you were to add a new character type, D, you would be unable to compile without having made sure your visitor implementations were updated to include logic for D as soon as you implement D's Accept method.
With dynamic dispatch, your fall-through method would be hit for any newly added character types if the attacking type doesn't have, for instance, an added Attack(D d) overload.
That said, dynamic dispatch has a much lower implementation overhead, but you give up some compile-time type safety. You'll have to assess which trade-off is more important for your use case.
Just use already built into C# typeof() here is some example code.
public class Program
{
public static void Main()
{
A a = new A();
B b = new B();
a.Attack(b);
b.Attack(a);
Console.WriteLine(typeof(A));
Console.WriteLine(typeof(B));
Console.WriteLine(typeof(A) == a.GetType());
Console.WriteLine(typeof(B) == a.GetType());
Console.ReadLine();
}
public abstract class Character
{
public abstract void Attack(Character c);
}
public class A : Character
{
public override void Attack(Character t)
{
if (t.GetType() == typeof(A))
{
Console.WriteLine("A attacked type A");
return;
}
if (t.GetType() == typeof(B))
{
Console.WriteLine("A attacked type B");
return;
}
if (t.GetType() == typeof(C))
{
Console.WriteLine("A attacked type C");
return;
}
}
}
public class B : Character
{
public override void Attack(Character t)
{
if (t.GetType() == typeof(A))
{
Console.WriteLine("B attacked type A");
return;
}
if (t.GetType() == typeof(B))
{
Console.WriteLine("B attacked type B");
return;
}
if (t.GetType() == typeof(C))
{
Console.WriteLine("B attacked type C");
return;
}
}
}
public class C : Character
{
public override void Attack(Character t)
{
if (t.GetType() == typeof(A))
{
Console.WriteLine("C attacked type A");
return;
}
if (t.GetType() == typeof(B))
{
Console.WriteLine("C attacked type B");
return;
}
if (t.GetType() == typeof(C))
{
Console.WriteLine("C attacked type C");
return;
}
}
}
}
All those answers were very interesting, even if some of the concepts went over my head.
Reading them I finally realized that there was no real problem (don't know why I created one but you know...), it's not really good looking but going for the simpliest solution I opted for the following :
I'll just consider the most common procedure and write it as the way to go for all classes that inherit from the abstract class. Then I can specify the methods for those that have a particular way of working the attack.
So let's say that when a class A character has the same way of attacking a class A or B character but attacks differently characters of type C. Using polymorphism we just have to do :
public abstract class Character
{
public abstract void Attack(Character t);
}
public class A :Character
{
public override void Attack(Character t)
{
/*instructions for the attacking of a character of type A or B*/
}
public void Attack(C z)
{
/*instructions for the attacking of a type C character*/
}
}
The general method (the one that takes a character parameter) will be use for any character type object (or that inherits from character) except if it's a type C object/character; in this case it will be dispatched to the Attack method that takes a type C object/character as parameter.
And if all tree types are attacked a different way then we can just choose arbitrarily one of them to be implemented following the abstract method signature :
public abstract class Character
{
public abstract void Attack(Character t);
}
public class A :Character
{
public override void Attack(Character t)
{
/*instructions for the attacking of a character of type A*/
}
public void Attack(B y)
{
/*instructions for the attacking of a type B character*/
}
public void Attack(C z)
{
/*instructions for the attacking of a type C character*/
}
}
Well, I don't know if that's dumbing it down too much but it works. The usage of dynamic, interface or generic types are probably good things but really there was nothing much to do here.
Thanks for the perspectives and please tell me if something isn't right.
To any fellow noob reading that I'd recommand to look at the elegant solution to a close problem (one that actually exists) presented in the section 3 of an article written by Eric Lippert on his blog that can be found following this link : https://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/
Since you know that you are only having 3 different types why dont you just create 3 abstract methods for each type in your Charackter class?
public abstract class Character
{
public abstract void Attack(A a);
public abstract void Attack(B a);
public abstract void Attack(C a);
}

Nested abstract class in an abstract class and how to implement it

I have an abstract class A and a abstract method with a parameter which is again abstract class B defined in the same abstract class A. When I extended this abstract class A as apart of another class C how can I implement the method with parameter of nested abstract class.
public abstract class A<T, V>
{
public abstract int GetObject(T t, V v);
public abstract int GetAnotherObject(B b);
public abstract class B{}
}
This class is extended by another class C
public class C: A<ABC, DEF>
{
public C()
{
}
public override int GetObject(ABC abc, DEF def)
{
return 10;
}
public override int GetAnotherObject(B b)
{
return 15;
}
}
How to implement class B with some properties and pass in GetAnotherObject method. Could someone please help me.
From ECMA:
Any class nested inside a generic
class declaration or a generic struct
declaration (ยง25.2) is itself a
generic class declaration, since type
parameters for the containing type
shall be supplied to create a
constructed type.
So, you cannot implement nested B without providing type arguments for A.
void Main()
{
var c = new C();
var result = c.GetAnotherObject(new BImpl<string, int>());
}
public class BImpl<T, V> : A<T, V>.B
{
public override int BM()
{
return 1;
}
}
// Or you can supply type arguments right here
//public class BImpl : A<string, int>.B
//{
// public override int BM()
// {
// return 1;
// }
//}
public abstract class A<T, V>
{
public abstract int GetObject(T t, V v);
public abstract int GetAnotherObject(B b);
public abstract class B
{
public abstract int BM();
}
}
public class C : A<string, int>
{
public C()
{
}
public override int GetObject(string abc, int def)
{
return 10;
}
public override int GetAnotherObject(B b)
{
return b.BM();
}
}
You're very close already.
public class C<ABC, DEF> : A<ABC, DEF>
{
public C()
{
}
public override int GetObject(ABC abc, DEF def)
{
return 10;
}
// since B is a nested class of A, it has no scope outside of A
// outside of the definition of A, it must always be referred to as A.B
public override int GetAnotherObject(A<ABC,DEF>.B b)
{
return 15;
}
}
public class D : A<ABC,DEF>.B
{
// implementation of A.B
}
Keep in mind that C will always take exactly A.B. You will never be able to define an implementation of A.B (let's call it D) and have C's method signature refer to that in the override. GetAnotherObject is defined in A as taking an A.B and must therefore be implemented to accept any A.B, not some specific implementation of A.B.
RE: your comment on how to implement A.B inside C
There is no point to implementing A.B inside C. C will still have to have A.B in its method signature. But if you really must, for some reason.
public class C<ABC, DEF> : A<ABC, DEF>
{
// C's implementation of A
public override int GetAnotherObject(A<ABC,DEF>.B b)
{
return 15;
}
public class D : A<ABC,DEF>.B
{
// implementation of A.B
}
}
Note that GetAnotherObject still takes an A.B, not a D.
How about
public class C<ABC, DEF> : A<ABC, DEF>
{
public C()
{
}
public override int GetObject(ABC abc, DEF def)
{
return 10;
}
public override int GetAnotherObject(B b)
{
return 15;
}
}
Just postfix the class with the generics.

Can I create a bag of objects that will hold different kinds o generic objects?

This one was hard to come up with a good title, so I gave my best shot at it.
Here is the problem:
Dictionary<string,ILayer> _layers = new Dictionary<string,ILayer>();
_layers.Add("IntLayer",new Layer<int>());
_layers.Add("GuidLayer",new Layer<Guid>());
Guid value = _layers["GuidLayer"].GetValue(int x, int y);
The classes:
public class Layer<T> : ILayer
{
public T[,] Matrix { get; set; }
public T GetValue(int x, int y)
{
return Matrix[x, y];
}
}
public interface ILayer
{
//T GetValue(int x, int y);
}
The idea is to be able to store different kinds of layers, and avoid the explicit casting. Although one would know the type when trying to get a value so it could be casted safely, but if I ever want to apply something across the layer it would make things a little more complicated there for a "generic" method would be better.
Is it possible to create this scenario? Should I be going a completely different way about this problem?
Thanks for any help
If you want to avoid explicit casting in the client code, there are couple of options I can think about:
Option 1
public interface ILayer
{
U GetValue<U>(int x, int y);
}
public class Layer<T> : ILayer
{
public T[,] Matrix { get; set; }
U ILayer.GetValue<U>(int x, int y)
{
return (U) (object) Matrix[x, y];
}
}
Option 2
public interface ILayer
{
}
public class Layer<T> : ILayer
{
public T[,] Matrix { get; set; }
public T GetValue(int x, int y)
{
return Matrix[x, y];
}
}
public static class LayerExtensions
{
public static U GetValue<U>(this ILayer layer, int x, int y)
{
return ((Layer<U>)layer).GetValue(x, y);
}
}

Double dispatch in C# 4.0 - dynamic keyword?

I realise this has been asked before, but I didn't find a clear agreement on the best solution.
Is using dynamic (like below) the best way to do this?
I guess its best to avoid dynamic whenever possible to help catch problems at compile-time.
(classA1 and classA2 implement Interface A and likewise for B)
public static void Foo(InterfaceA a, InterfaceB b)
{
Foo((dynamic)a, (dynamic)b);
}
static void Foo(classA1 a, classB1 b) { //some code }
static void Foo(classA2 a, classB2 b) { //some code }
static void Foo(classA1 a, classB2 b) { //some code }
static void Foo(classA2 a, classB1 b) { //some code }
Or similarly...
public static void Foo(InterfaceA a, InterfaceB b)
{
((dynamic) a).Foo(b);
}
public classA1
{
void Foo(classB1 b) { //some code }
}
//repeated for other cases
Is using dynamic (like below) the best way to do this?
Well it's a way to do it - so long as the execution-time types will always end up with something that overload resolution will be happy with.
You might want to put a backstop method of
static void Foo(object x, object y)
in case none of the methods are applicable (e.g. a is a non-ClassA1/ClassA2 implementation). It's not going to help you if both values are null, mind you...
I would usually attempt to redesign so that this isn't required, but it's hard to know the best solution without more context.
Are 'classA1' and so on implementations of InterfaceA? If so then why not just declare the Foo functions as accepting InterfaceA and InterfaceB and cast them within to the concrete implementation expected by the function? E.g.,
static void Foo(InterfaceA a, InterfaceB b) {
classA1 c1 = a as classA1;
classB1 b1 = b as classB1;
// ... etc
}
Dynamic isn't intended to be used this way.
You could do something AWFUL with reflection - but I'm sure it's not better than doing dynamic:
void Main()
{
var a = "hello";//5;
var b = "hello";
var type1 = a.GetType();
var type2 = b.GetType();
var t = typeof(FooClass);
var methods = t.GetMethods();
foreach(var method in methods)
{
var parameters = method.GetParameters();
if(parameters.Length == 2)
{
if(parameters[0].ParameterType == type1
&& parameters[1].ParameterType == type2)
{
method.Invoke(this, new object[]{ a, b });
}
}
}
}
public static class FooClass
{
public static void Foo(int i, string s)
{
"Foo1".Dump();
}
public static void Foo(string s, string s2)
{
"Foo2".Dump();
}
}
C# has traditionally been a statically-typed language. The dynamic keyword adds dynamic typing to the language. The usual advice is to use "dynamic" sparingly. Here may be a case where you need it.
Generics won't cut it as this won't compile:
private void button1_Click(object sender, EventArgs e)
{
Foo(new classA1(), new classB2());
}
static void Foo<T, T1>(T a, T1 b) where T: InterfaceA
where T1: InterfaceB
{
Foo2(a, b);
}
static void Foo2(classA1 a, classB1 b) { }
static void Foo2(classA2 a, classB2 b) { }
static void Foo2(classA1 a, classB2 b) { }
static void Foo2(classA2 a, classB1 b) { }
interface InterfaceA { }
interface InterfaceB { }
class classA1 : InterfaceA { }
class classA2 : InterfaceA { }
class classB1 : InterfaceB { }
class classB2 : InterfaceB { }

Categories