Repeated template in class methods - c#

suppose I have this class:
Class Foo:
method1(){}
method2(){}
method3(){}
...
And suppose I have some action I wanted to do repeatedly in several methods in the class. Each action will take before the methods occur and after it occur. Is there an elegant way to implement it? The only way came to my mind:
private void Setup(Action action)
{
//Do something before
action
//Do something after
}
private void method1(args)
{
Setup(()=>method)
}
But it will make me call repeatedly call for Setup in each function I would like to implement it.

I have made a quick exemple with DispatchProxy
Inspiration : DispatchProxy
https://dotnetfiddle.net/GzDR9r
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
//https://www.c-sharpcorner.com/article/aspect-oriented-programming-in-c-sharp-using-dispatchproxy/
public class Program
{
public static void Main()
{
var foo = new Foo();
var decoratedFoo = AspectDecorator<IFoo>.Create(foo);
Console.WriteLine("\n\nClass:\n");
foo.method1();
foo.method2();
foo.method3();
Console.WriteLine("\n\nDecorated Class:\n");
decoratedFoo.method1();
decoratedFoo.method2();
decoratedFoo.method3();
}
}
public class Foo : IFoo{
public void method1(){Console.WriteLine("> call method1");}
public void method2(){Console.WriteLine("> call method2");}
public void method3(){Console.WriteLine("> call method3");}
}
public interface IFoo{
void method1();
void method2();
void method3();
}
public class AspectDecorator<T> : DispatchProxy
{
private T _impl;
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
Console.WriteLine($"Before : {targetMethod.Name}");
var obj = _impl.GetType().GetMethod(targetMethod.Name).Invoke(_impl, args);
Console.WriteLine($"After : {targetMethod.Name}");
return obj;
}
public void SetTarget(T target)
{
this._impl = target;
}
public static T Create(T decorated)
{
object proxy = Create<T, AspectDecorator<T>>();
((AspectDecorator<T>) proxy)._impl=decorated;
return (T)proxy;
}
}

Related

What interface type is suited for implementing strategy with different signature?

consider the following game code:
public class Player : MonoBehaviour {
public void UseItem(Item item) {
item.Use(this);
}
public void GetDrunk() {}
}
public class Item {
public WhatInterface[] itemUsages;
public void Use(Player player) {
foreach(var usage in itemUsages) {
usage.Execute(new ItemUsageArgs {itemUser = player, itemUsed = this})
}
}
}
public class GameManager : MonoBehaviour {
public Player mainCharacter;
public Item beer = new Item {itemUsages = new [] {
new TestConsole(),
new DamageFromItem (),
new DrunkFromITem ()
}}
private void Start() {
mainCharacter.Use(beer);
}
}
public class TestConsole : WhatInterface {
public void Execute(BaseArgs args) {
Debug.Log("function call executed");
}
}
public class DamageFromItem : WhatInterface {
public void Execute(ItemUsageArgs args) {
Debug.Log(args.itemUser + " take damage from " + args.itemUsed);
}
}
public class DrunkFromITem : WhatInterface {
public void Execute(ItemUsageArgs args) {
args.itemUser.GetDrunk();
}
}
public class BaseArgs {}
public class ItemUsageArgs : BaseArgs {
public Player itemUser;
public Item itemUsed;
}
so how to create interface type code that is suited for itemUsages?
Or do I wrongly create the design for this context?
Basically I'm trying strategy pattern so that item usages could be vary for every kind of item.
Things I tried, creating IItemUsage interface:
public interface IItemUsage {
void Execute(ItemUsageArgs args);
// but then anything that needs to implement this interface must use this method, even though it only needs BaseArgs.
// TestConsole class must conform to Execute(ItemUsageArgs) signature..
}
public class TestConsole : IItemUsage {
public void Execute(BaseArgs args) {
Debug.Log("function call executed");
}
// this won't compile
}
Assuming this is all of your code, you can make IItemUsage generic, and contravairant on the generic parameter.
public interface IItemUsage<in T> where T: BaseArgs {
void Execute(T args);
}
Have TestConsole implement IItemUsage<BaseArgs> and the other two classes implement IItemUsage<ItemUsageArgs>.
Now you can put instances of all three classes into an IItemUsage<ItemUsageArgs>[]:
IItemUsage<ItemUsageArgs>[] arr = new IItemUsage<ItemUsageArgs>[] {
new TestConsole(), new DamageFromItem(), new DrunkFromITem()
};
If you want to implement interface with some method, which has input arguments, that can be different types, you must define base argument class or use interface parameter instead.
For example:
public interface IItemUsage
{
void Execute(IItemUsageArgs args);
}
public interface IItemUsageArgs
{
//place public part of all ItemUsageArgs
}
public class ItemUsageArgs1 : IItemUsageArgs
{
}
public class ItemUsageArgs2 : IItemUsageArgs
{
}
public class ItemUsage1 :IItemUsage
{
public void Execute(ItemUsageArgs1 args)
{
//do you need
}
void IItemUsage.Execute(IItemUsageArgs args)
{
Execute(args as ItemUsageArgs1);
}
}
public class ItemUsage2 : IItemUsage
{
public void Execute(ItemUsageArgs2 args)
{
//do you need
}
void IItemUsage.Execute(IItemUsageArgs args)
{
Execute(args as ItemUsageArgs2);
}
}

load different class of same type based on name

This is a really simple structure question, but i don't know what is the best way to do this in C#.
I need a "base" class or something to allow me load diferent "levels" in the "level" object, and changing the name I can swith the class what I want to use.
Now i'm using a abstract class and instance of the childrens in this way:
using UnityEngine;
using System;
public class Level : MonoBehaviour {
public levelClass level;
public void initLevel(string className) {
Type t = Type.GetType(className);
level = (levelClass)Activator.CreateInstance(t, new object[] { });
level.Start();
}
void Start () {
Debug.Log("Levels: Start");
initLevel("worldTwo");
}
void Update () {
level.Update();
}
}
public abstract class levelClass {
public abstract void Start();
public abstract void Update();
}
public class worldOne : levelClass {
public override void Start() {
Debug.Log("worldOne: Start");
}
public override void Update() {
Debug.Log("worldOne: Update");
}
}
public class worldTwo : levelClass
{
public override void Start()
{
Debug.Log("worldTwo: Start!");
}
public override void Update()
{
Debug.Log("worldTwo: Update!");
}
}
But I think exists better ways to do, like store all classes in a list and call it or something similar. The part i don't like nothing is have some classes public in this file (I know i can split in other files, i'm trying to think only in a way to do this better)

Quickly reference static methods

Is it by any chance possible to call a method without referencing to its class?
For instance, you have a helper class:
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
And then you need to call it:
class MainClass
{
public static void Main()
{
HelperTools.DoWork();
}
}
Is it possible to call DoWork(); without a reference? Like this:
public static void Main()
{
DoWork();
}
Just for sake of simplicity.
Not quite, but here are 5 patterns that get you close:
namespace My.Namespace
{
using H = MyHelperClass;
public class MyHelperClass
{
public static void HelperFunc1()
{
Console.WriteLine("Here's your help!");
}
}
public class MyHelperClass2
{
public static void HelperFunc4()
{
Console.WriteLine("Here's your help!");
}
}
public interface IHelper{ }
public static class HelperExtensions
{
public static void HelperFunc3(this IHelper self)
{
Console.WriteLine("Here's your help!");
}
}
public class MyClass : MyHelperClass2, IHelper
{
private static readonly Action HelperFunc2 = MyHelperClass.HelperFunc1;
private static void HelperFunc5()
{
Console.WriteLine("Here's your help!");
}
public void MyFunction()
{
//Method 1 use an alias to make your helper class name shorter
H.HelperFunc1();
//Method 2 use a class property
HelperFunc2();
//Method 3 extend an interface that has extension methods.
//Note: you'll have to use the this keyword when calling extension
this.HelperFunc3();
//Method 4 you have access to methods on classes that you extend.
HelperFunc4();
//Method 5 put the helper method in your class
HelperFunc5();
}
}
}
No. Java has the concept of importing static like this, but C# does not. (IMO, a naked DoWork() without any clue as to where the implementation resides is non-ideal.)
a few years late but maybe this will help someone else...
Use a using static directive to reference the static class: (introduced in C# 6)
using static HelperTools;
class MainClass
{
public static void Main()
{
DoWork();
}
}
---------------- HelperTools.cs--------------------
class HelperTools
{
public static void DoWork()
{ /*...*/ }
}
The only place you can call DoWork from without referencing the class name is within the class itself. For instance, if you add a non-static method to HelperTools:
public void foo()
{
DoWork();
}
You can call DoWork from within it, even though foo() is not static.

adding methods from class A to a delegate of class B and calling that delegate from class A in C#

How can I add a method from class A to a delegate of class B without knowing in advance which method I will be adding and what class A is? And then call that delegate from class A?
class Class {
public string someProperty;
public delegate void myDelegate(Class obj);
myDelegate handler = new myDelegate(mainClassMethod); //here is the problem..
public void someMethod() {
handler();
}
}
class MainClass {
public static void Main() {
Class classObj = new Class();
classObj.someProperty = "hello";
public void mainClassMethod(Class obj) {
System.Console.WriteLine(obj.someProperty);
}
classObj.someMethod();
}
}
Should I use something other than delegates for this? By the way I am doing this in C#!
make mainClassMethod static and access it via class name MainClass. Also you cant declare nested functions as class members, you need to declare mainClassMethod separately.
class MainClass {
public static void Main()
{
Class classObj = new Class();
classObj.someProperty = "hello";
classObj.someMethod();
}
public static void mainClassMethod(Class obj)
{
System.Console.WriteLine(obj.someProperty);
}
}
Also you declared delegate void myDelegate(Class obj); so you need to pass instance of a Class as a parameter. In my example I pass object found by this reference, which is an object that you call someMethod at.
Now you can write:
class Class {
public string someProperty;
public delegate void myDelegate(Class obj);
myDelegate handler = new myDelegate(MainClass.mainClassMethod); //no error
public void someMethod()
{
handler(this);
}
}

Attaching overrides to a C# class

I have a class with functions:
class MyClass
{
public List<Attachment> Attachments;
public void A()
{
// Do something
}
public void B()
{
// Do something
}
}
class AttachmentA : Attachment
{
public void A()
{
// Do something else
RealA();
}
}
class AttachmentB : Attachment
{
public void B()
{
// Do something else
// RealB();
// No need to call base function here
}
}
I need in my code when I attach AttachmentA to MyClass that all the functions in MyClass that are also present in AttachmentA to be overridden by the functions in AttachmentA and also give access to the original functions in MyClass.
For example, I create MyClass and then attach AttachmentA instance to it. calling MyClass.A() will actually call AttachmentA.A() and the AttachmentA.RealA() will call the base function that was overridden.
I know this can be somehow done with something like using event handlers lists to handle overrides but is there an easy way to implement this?
Edit: I have no problem with long code that uses reflection as long as its present once and doesn't have to be even mentioned in any of the functions - maybe only when attaching attachement.
Edit: you wanted an example:
class MyClass
{
public List<Attachment> Attachments;
public MyClass()
{
Attachments = new List<Attachment>();
}
public void Attach(Attachment attachment)
{
Attachments.Add(attachment);
// Do some magic here
}
public void A()
{
Console.WriteLine("MyClass.A");
}
public void B()
{
Console.WriteLine("MyClass.B");
}
}
class AttachmentA : Attachment
{
public void A()
{
Console.WriteLine("AttachmentA.A");
RealA();
}
}
class AttachmentB : Attachment
{
public void B()
{
Console.WriteLine("AttachmentB.B");
}
}
public class Program
{
public static void Main(string[] Args)
{
MyClass aaa = new MyClass();
aaa.A(); // should print MyClass.A
aaa.B(); // should print MyClass.B
aaa.Attach(new AttachmentA());
aaa.Attach(new AttachmentB());
aaa.A(); // should print AttachmentA.A <newline> MyClass.A
aaa.B(); // should print AttachmentB.B
}
}
Edit: What I want to achieve here is like unit with attributes( = attachments). When the unit get an attachment of RandomSpeed, RandomSpeed will override the unit's GetSpeed and return random value. when it will get an attachment of evasion, it will override that units ReduceHP function and sometimes based on random value will not call the base function.
Edit: What will really solve this mess is to somehow use reflection to change virtual method tables, I'm gonna make a followup on a separate question. I keep this question here incase someone find a better way to do this.
As mentioned in comments, Decorator Pattern is what you are looking for.
http://en.wikipedia.org/wiki/Decorator_pattern
The decorator pattern can be used to
make it possible to extend (decorate)
the functionality of a certain object
at runtime, independently of other
instances of the same class, provided
some groundwork is done at design
time. This is achieved by designing a
new decorator class that wraps the
original class.
Why not take another approach? Have attachments implement interfaces based on what they want to override, for example ISpeedAttachment. Then you could, in the base speed function loop through attachments which implement ISpeedAttachment, calling them.
Have the interfaces return null if they haven't taken effect and you could then check they've all returned null and call the base class as appropriate, or pass in a ref parameter which you could adjust as necessary.
You should look into the behavioral patterns. For your particular problem I would recommend either the chain of responsibility or the strategy pattern.
If you don't want to introduce dependencies, like inheritance or interfaces to implement on MyClass then:
You can achieve this through delegates.
Long story short, you cannot override function in runtime without resorting to some obscure reflection magic, but you can declare delegates instead of functions. When you construct your class in the constructor fill the delegates with private methods which will be used for as long as no AttachmentA class comes in. And use those delegates instead of the methods.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
static class Program
{
static void Main(string[] args)
{
MyClass aaa = new MyClass();
aaa.A(); // should print MyClass.A
aaa.B(); // should print MyClass.B
aaa.Attach(new AttachmentA());
aaa.Attach(new AttachmentB());
aaa.A(); // should print AttachmentA.A <newline> MyClass.A
aaa.B(); // should print AttachmentB.B
}
}
class MyClass
{
public List<Attachment> Attachments;
public MyClass()
{
A = _A;
B = _B;
Attachments = new List<Attachment>();
}
public void Attach(Attachment attachment)
{
Attachments.Add(attachment);
// this is your magic
if (attachment.GetType() == typeof(AttachmentA)) {
A = ((AttachmentA)attachment).A;
}
else if (attachment.GetType() == typeof(AttachmentB))
{
B = ((AttachmentB)attachment).B;
}
}
public delegate void delegateA();
public delegate void delegateB();
public delegateA A;
public delegateB B;
public void _A()
{
Console.WriteLine("MyClass.A");
}
public void _B()
{
Console.WriteLine("MyClass.B");
}
}
class Attachment {
}
class AttachmentA : Attachment
{
public void A()
{
Console.WriteLine("AttachmentA.A");
}
}
class AttachmentB : Attachment
{
public void B()
{
Console.WriteLine("AttachmentB.B");
}
}
}
If you need the execution to start always in MyClass instead of the Attachment class you can wrap the delegates like here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
static class Program
{
static void Main(string[] args)
{
MyClass aaa = new MyClass();
aaa.A(); // should print MyClass.A
aaa.B(); // should print MyClass.B
aaa.Attach(new AttachmentA());
aaa.Attach(new AttachmentB());
aaa.A(); // should print AttachmentA.A <newline> MyClass.A
aaa.B(); // should print AttachmentB.B
}
}
class MyClass
{
public List<Attachment> Attachments;
public MyClass()
{
Attachments = new List<Attachment>();
}
public void Attach(Attachment attachment)
{
Attachments.Add(attachment);
if (attachment.GetType() == typeof(AttachmentA)) {
_A = ((AttachmentA)attachment).A;
}
else if (attachment.GetType() == typeof(AttachmentB))
{
_B = ((AttachmentB)attachment).B;
}
}
public delegate void delegateA();
public delegate void delegateB();
public delegateA _A;
public delegateB _B;
public void A()
{
if (_A != null)
{
_A();
}
else
{
Console.WriteLine("MyClass.A");
}
}
public void B()
{
if (_B != null)
{
_B();
}
else
{
Console.WriteLine("MyClass.B");
}
}
}
class Attachment {
}
class AttachmentA : Attachment
{
public void A()
{
Console.WriteLine("AttachmentA.A");
}
}
class AttachmentB : Attachment
{
public void B()
{
Console.WriteLine("AttachmentB.B");
}
}
}
You can shorten this to one delegate type if A and B have the same parameters and return type in your real scenario.
I'm not sure if dynamically overriding a class's functionality is possible, but you can achieve something similar by using different interfaces. Depending on the context you want to use this in, it may require only small redesign.
The standard way of doing it would be this:
using System;
class MyClass
{
public virtual void A()
{
Console.WriteLine("MyClass.A");
}
public virtual void B()
{
Console.WriteLine("MyClass.B");
}
}
class ClassA : MyClass
{
public override void A()
{
Console.WriteLine("AttachmentA.A");
base.A();
}
}
class ClassB : MyClass
{
public override void B()
{
Console.WriteLine("AttachmentB.B");
}
}
public class Program
{
public static void Main(string[] Args)
{
MyClass aaa = new ClassA();
MyClass bbb = new ClassB();
aaa.A(); // prints MyClass.A
aaa.B(); // prints MyClass.B
(aaa as ClassA).A(); // prints AttachmentA.A
(aaa as ClassA).B(); // prints MyClass.B
bbb.A(); // prints MyClass.A
bbb.B(); // prints MyClass.B
(bbb as ClassB).A(); // prints AttachmentB.A + MyClass.A
(bbb as ClassB).B(); // prints AttachmentB.B
}
}
Here's another example, similar to what blowdart suggested:
interface ICallMe
{
bool A();
bool B();
}
class MyClass
{
public ICallMe Attachment { get; set; }
public void A()
{
bool BaseFunction = true;
if (Attachment != null)
BaseFunction = Attachment.A();
if (BaseFunction)
Console.WriteLine("MyClass.A");
}
public void B()
{
bool BaseFunction = true;
if (Attachment != null)
BaseFunction = Attachment.B();
if (BaseFunction)
Console.WriteLine("MyClass.B");
}
}
class ClassA : ICallMe
{
public bool A()
{
Console.WriteLine("AttachmentA.A");
return true;
}
public bool B()
{
Console.WriteLine("AttachmentA.B");
return false;
}
}
static class Program
{
static void Main(string[] args)
{
MyClass aaa = new MyClass();
aaa.A(); // prints MyClass.A
aaa.B(); // prints MyClass.B
aaa.Attachment = new ClassA();
aaa.A(); // should print AttachmentA.A <newline> MyClass.A
aaa.B(); // should print AttachmentB.B
}
}
This only allows for a single attachment to be added. If you wanted to override the behavior of several functions separately, you could use a Collection of some sort to hold the attachments. Within the base class you'd need to loop through them and find the one you want to execute.

Categories