How to solve this problem about interfaces? I think I need this variable (and some others)in this especific class.
public interface Action
{
void execute();
}
public A:Action
{
public int misteriousNumber;
void execute()
{
int iUseMisteriousNumber = misteriousNumber;
}
}
public B:Action
{
void execute()
{
//I use nothing.
}
}
//Some Class...
static void Main(string[] args)
{
foreach(Action action in SecretRepositoryOfTheActions.actions)
{
if(action is A)
(SomeTypeOfCasting to A)action.misteriousNumber=13;
action.execute();
}
}
Just the 'A' class have this property not other Action classes what to use to access it (casting, not interfaces other implementation)?
You have to cast it, first check the type with is:
foreach(Action action in SecretRepositoryOfTheActions.actions)
{
if(action is A)
((A) action).misteriousNumber = 13;
action.execute();
}
If you only wanted to process A-objects (which doesn't seem to be the case):
foreach(A a in SecretRepositoryOfTheActions.actions.OfType<A>())
{
a.misteriousNumber = 13;
a.execute();
}
Related
I'm new to passing delegates and was wondering if the following code is possible to do?
CommandQueue.AddCommand(
new CommandItem(
group.MyGroupActionMovement(
new Vector3(-1000,-1000,-1000))));
ok to elaborate I'm going to do a code dump of my bad attempt at the command pattern...
So I'm trying to create a queue of commands. Starting with just the movement command. It takes a vector3 as a parameter. Other Commands will have different parameters like enums and game objects.
This is supposed to be my interface for commands/actions but, I've been messing with it to see what I can do.
public class IGroupAction: MonoBehaviour
{
public delegate bool Del(Vector3 destination);
public virtual bool Execute()
{
return true;
}
}
This is supposed to be the command/action unit/item
public class GroupActionItem
{
public IGroupAction MyGroupAction;
public GroupActionItem(IGroupAction.Del action)
{
}
public bool PerformAction()
{
return MyGroupAction.Execute();
}
}
This is the command pattern that I've completed so far
public class GroupAction
{
public List<GroupActionItem> Actions;
public GroupAction()
{
Actions = new List<GroupActionItem>();
}
public void AddAction(GroupActionItem groupActionItem)
{
Actions.Add(groupActionItem);
}
public void ClearActions()
{
Actions.Clear();
}
public void PerformActions()
{
if (Actions.Count >= 1)
{
if(Actions[0].PerformAction())
{
Actions.Remove(Actions[0]);
}
}
}
}
This is where I execute the movement command
public class GroupActionMovement : IGroupAction
{
public override bool Execute()
{
return Movement();
}
public bool Movement(Vector3 destination)
{
return true;
}
}
public class Group : MonoBehaviour
{
public GroupActionMovement MyGroupActionMovement;
}
This is the execution of the coded behavior.
public class Player : MonoBehaviour
{
public Dictionary<Group,GroupAction> PlayerGroupsActions;
public List<Group> Groups;
void Start()
{
PlayerGroupsActions = new Dictionary<Group, GroupAction>();
Groups = GetComponentsInChildren<Group>().ToList();
foreach (Group group in Groups)
{
GroupAction playerGroupActions = new GroupAction();
PlayerGroupsActions.Add(group,playerGroupActions);
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
//remove the foreach
foreach (Group group in Groups)
{
//directly apply the group
PlayerGroupsActions.TryGetValue(group, out GroupAction playerGroupActions);
if (playerGroupActions != null)
{
playerGroupActions.AddAction(new GroupActionItem(group.MyGroupActionMovement.Movement));
}
}
}
foreach (Group group in Groups)
{
PlayerGroupsActions.TryGetValue(group, out GroupAction playerFormationActions);
if (playerFormationActions != null)
{
if (playerFormationActions.Actions.Count != 0)
{
playerFormationActions.PerformActions();
}
}
}
}
}
I'm sorry if this isn't the best explanation of what is going on or, that a code dump is not the best way to explain what i'm doing.
don't pass it as a method, use something like this
CommandQueue.Command += doSomething;
void doSomething()
{
//doSomething
}
So that whenever the function CommandQueue.Command is run in the seperate class it will also run the doSomething() void in the main class
A delegate is not a method call, but the method it self, for the receiver to call it, whenever its needs to, with the parameters it wants.
Here is an example:
public delegate int MyDelegate(Vector3 vec);
public class MyCallingClass
{
public void DoSomething(MyDelegate method)
{
// Do something.
int result = method(new Vector3(-1000, -1000, -1000));
// Do something else.
}
}
public class MyClass
{
public static int MyStaticMethod(Vector3 arg)
{
// Do something with arg.
return x;
}
int MyMethod(Vector3 arg)
{
// Do something with arg.
return x;
}
private void DelegateWork()
{
MyCallingClass c = // Get an instance of MyCallingClass.
c.DoSomething(this.MyMethod);
c.DoSomething(MyClass.MyStaticMethod);
}
}
Multiple things to understand here:
At line c.DoSomething(this.MyMethod), the this is captured into the delegate you pass, meaning that when MyCallingClass.DoSomething will call the delegate, it will be called on the instance of MyClass. The line c.DoSomething(MyClass.MyStaticMethod) will call it with no instance, because it is a static method.
This is the method MyCallingClass.DoSomething that decides what parameters to pass, not the one that provides the delegate.
If you need the caller to provide arguments and the calling part to just decide when to call but not deciding what arguments to pass, then you can capture the argument ahead of time, and pass a delegate without argument, as follow.
public delegate int MyDelegate(); // No arguments anymore.
public class MyCallingClass
{
public void DoSomething(MyDelegate method)
{
// Do something.
int result = method(); // Not passing arguments anymore.
// Do something else.
}
}
public class MyClass
{
// ...
private void DelegateWork()
{
MyCallingClass c = // Get an instance of MyCallingClass.
c.DoSomething(() => this.MyMethod(new Vector3(-1000, -1000, -1000)));
c.DoSomething(() => MyClass.MyStaticMethod(new Vector3(-1000, -1000, -1000));
}
}
If you are not familiar with the syntax () => ..., this is a lambda expression, you can see it as an anonymous function created on-the-fly. It still respects the prototype returning an int and taking no parameters. The lambda expression now captures the construction of the Vector3 instance, and so this value will be used when the lambda will be called. A very important aspect to understand is that the values in the lambda expressions are evaluated when the lambda is called, not when it is created (lazy evaluation).
You do not have to use a specific delegate but instead you can use a Func<Vector3, int>, as follow:
// Not actually needed.
// public delegate int MyDelegate(Vector3 vec);
public class MyCallingClass
{
public void DoSomething(Func<Vector3, int> method)
{
...
}
}
I am wondering how I should have written the following code?
I wanted to have a base class, and have one of the derived classes override one of the methods in the base class. But I need a different signature for the method that is to be overridden (To complicate things more, that method is buried in a loop).
How should I have properly structured the following code to accomplish the equivalent of overriding a method with a different signature?
(Getting rid of the abstract declaration is OK to do)
abstract class ClassBase
{
public void LoopThroughStuff(int i)
{
for (i = 0; i < 10; i++)
{
//DO A BUNCH OF STUFF
var k = (something determined in loop) //THIS IS USED IN Class2's DoSomething(i,k)
DoSomething(i); //THIS NEEDS TO BE OVERRIDDEN IN Class2 WITH ADDITIONAL PARAMETER, WHICH I KNOW CAN'T BE DONE
//DO A BUNCH OF STUFF
}
}
public virtual void DoSomething1(int x)
{
//DO STUFF
}
}
public class Class1 : ClassBase
{
}
public class Class2 : ClassBase
{
public override void DoSomething1(int j, int k) //I KNOW THIS CAN NOT BE DONE
{
//DO STUFF
}
}
There are a number of options. Here's one: use generics.
abstract class ClassBase<T>
{
public abstract void DoSomething(T args);
}
public class Class1 : ClassBase<Class1Args>
{
public void DoSomething(Class1Args args);
}
public class Class1Args
{
public int x;
}
public class Class2 : ClassBase<Class2Args>
{
public void DoSomething(Class2Args args);
}
public class Class2Args
{
public int j;
public int k;
}
Inheritance may be overkill for what you're doing. Reverse your thinking and try a functional style instead.
Start with an array or list (of any type) then use the Select method with a lamba or Func object that will "map" or perform a transform on each element of the array and return a new array or list.
string [] array = {"element1", "element2"};
Func<string, string> DoSomething = (x) => x.ToUpper();
var result = array.Select(DoSomething);
or more succinctly:
var result = array.Select(x => x.ToUpper());
Do the base class like the following code, which uses Function overloading which is a type of Polymorphism. a starting reference for basic OOP can be found here
abstract class ClassBase
{
public virtual void LoopThroughStuff(int i)
{
for (i = 0; i < 10; i++)
{
//DO A BUNCH OF STUFF
DoSomething(i);
//DO A BUNCH OF STUFF
}
}
public virtual void DoSomething1(int x)
{
//DO STUFF
}
public virtual void DoSomething1(int j, int k)
{
//you can keep this empty, as you will override it in Class2
}
}
public class Class2 : ClassBase
{
public override void LoopThroughStuff(int i)
{
for (i = 0; i < 10; i++)
{
//DO A BUNCH OF STUFF
// set k here as you like
DoSomething(i,k);
//DO A BUNCH OF STUFF
}
}
public override void DoSomething1(int j, int k)
{
//DO STUFF
}
}
I am working on some code whereby I have an abstract class that has a few core properties and a Run(int index) method. I then create new types that inherit this. These new types can have multiple methods that can be called according to the index passed in.
public abstract class BaseClass
{
public abstract void Run(int index);
}
public class Class1 : BaseClass
{
public override void Run(int index)
{
if (index == 0)
{
MethodA();
}
else if (index == 1)
{
MethodB();
}
}
private void MethodA()
{
//do stuff
}
private void MethodB()
{
//do stuff
}
}
I'm just wondering is there a better way to do this. These types and methods would be called from a UI, - a menu click for example. So I might have a class1 and a class2. Class1 might have 3 methods so I could call run(0) ... run(2) on it. Class2 might just have one internal method so I would just call run(0). Maybe I would need to keep a collection of ints with each class I guess as a map to methods. Might also have to add a string to this collection to hold a friendly name for menu items etc..
Can you think of a way to implement this type of mapping while maintaining as much abstraction as possible? Is there a better way to go about this that my current idea?
One way:
You could use an interface instead:
public interface IRunnableSomething {
void Run();
}
public class MyRunnableA :IRunnableSomething
{
public void Run() {
// do stuff
}
}
public class MyRunnableB :IRunnableSomething
{
public void Run() {
// do stuff
}
}
Then in your main class...
public override void Run(IRunnable runnable)
{
runnable.Run();
}
Example of calling it:
myInstanceOfMainClass.Run(new MyRunnableA());
This seems fitting, since you already know what index you were passing in with your original version. This just moves it from int based to interface based (less code too in the end).
Let me explain a bit further so. Here's a slightly more verbose version of what I am trying to do. You can see here that my abstract class has the list of indexes for pointing at the right method in derived classes, and you can see where I am loading types and creating menu items in a UI. I am using this ItemPointer list and passing around ItemPointers to tag properties etc. It all feels a bit wrong somehow.
I wish for the whole thing to be extensible. I might want to add a Class2, Class3 etc all inheriting BaseClass. I might also want to create plugins using BaseClass. Any derived class will have at least one but runable method but will likely have many. So Class1 here is just an example. Does this help explain myself? please go easy on me, I'm learning and that's why I am asking here.
Is what I'm doing here awful? or is it ok? or is there a better way? I guess that's my question. If there is a better way, I'd really appreciate an example. Many thanks to all for the help. It is much appreciated.
public abstract class BaseClass
{
public List<ItemPointer> ItemPointers = new List<ItemPointer>();
public abstract void Run(int index);
}
public class ItemPointer
{
public int Index { get; set; }
public string ClassType { get; set; }
public string UIDescription { get; set; }
}
public class Class1 : BaseClass
{
public Class1()
{
ItemPointers.Add(new ItemPointer { Index = 0, ClassType = this.GetType().Name, UIDescription = "MethodA Description" });
ItemPointers.Add(new ItemPointer { Index = 1, ClassType = this.GetType().Name, UIDescription = "MethodB Description" });
}
public override void Run(int index)
{
if (index == 0)
{
MethodA();
}
else if (index == 1)
{
MethodB();
}
}
private void MethodA()
{
//do stuff
}
private void MethodB()
{
//do stuff
}
}
public class UIForm
{
private List<BaseClass> _baseClasses;
//Formload events load all baseclass types (including plugins via reflection during form init etc. Then call loadUIitems
private void LoadUIItems()
{
foreach (BaseClass bc in _baseClasses)
{
foreach (var p in bc.ItemPointers)
{
ToolStripMenuItem t = new ToolStripMenuItem(p.UIDescription);
t.Click += new EventHandler(WorkerMenu_Click);
t.Tag = p;
actionsToolStripMenuItem.DropDownItems.Add(t);
}
}
}
void WorkerMenu_Click(object sender, EventArgs e)
{
ToolStripMenuItem t = (ToolStripMenuItem)sender;
ItemPointer p = (ItemPointer)t.Tag;
foreach (BaseClass bc in _baseClasses)
{
if (bc.GetType().Name == p.ClassType)
{
bc.Run(p.Index);
}
}
}
}
In your position I might be inclined to try do something like this:
void Main()
{
var a = new Class1();
var b = new Class2();
try
{
a.Run("Foo");
b.Run("Bar", "Yoda");
b.Run("Bat"); // throws exception
}
catch (Exception ex)
{
Console.WriteLine (ex.Message);
}
}
class Base
{
public void Run(string commandName, params object[] args)
{
var method = this.GetType().GetMethod(commandName);
if(method != null)
method.Invoke(this, args);
else
throw new Exception("the command " + commandName + " does not exist on " + this.GetType().Name);
}
}
class Class1 : Base
{
public void Foo()
{
Console.WriteLine ("I am foo");
}
}
class Class2 : Base
{
public void Bar(string str)
{
Console.WriteLine ("I am {0}", str);
}
}
Output:
I am foo
I am Yoda
the command Bat does not exist on Class2
I'm trying to expose an API such that, I do the following
RegisterCallback<T>(Action<T> func)
{
someObj.FuncPointer = func;
}
Later on, I call func(obj) .. and the obj is of type T that the user said.
More concrete example:
var callbackRegistrar = new CBRegistrar();
callbackRegistrar.RegisterCallback<ISomeClass>(SomeFunc);
public static void SomeFunc(ISomeClass data)
{
//
}
EDIT: So I may not have been clear, so I'll add more code:
I want to make only "one" object of CBRegistrar, and connect it with many Callbacks, as such:
var callbackRegistrar = new CBRegistrar();
callbackRegistrar.RegisterCallback<ISomeClass>(SomeFunc);
callbackRegistrar.RegisterCallback<ISomeOtherClass>(SomeFunc2);
...
In fact the above code is called by reflecting over a directory of plugins.
The user puts this in their code -->
public static void SomeFunc(ISomeClass data)
{
//
}
public static void SumFunc2(ISomeOtherClass data)
{
//
}
It looks to me as if this is not possible using Generics, etc. What it looks like I might have to do is make an interface called IPlugin or something, and ask the user to do this ..
[PluginIdentifier(typeof(ISomeClass))]
public static void SomeFunc(IPluginData data)
{
var castedStuff = data as ISomeClass; // ISomeClass inherits from IPluginData
}
Seems like asking the user to do stuff that we should take care of, but anyway ...
You need a Action<T> func to store it in. There is a semantic check to make here: if someone calls RegisterCallback twice (with different values), do you want to replace the callback, or keep both ? Assuming the latter, someObj probably wants an event (indeed, this entire API could be exposed as an event), so - in the someObj class:
public event Action<T> FuncPointer;
private void InvokeCallback(T data) {
var handler = FuncPointer;
if(handler != null) handler(data);
}
Noting that RegisterCallback could be replaced entirely, still keeping the data on obj:
public event Action<T> Completed {
add { obj.FuncPointer += value; }
remove { obj.FuncPointer -= value; }
}
Then usage would be:
var callbackRegistrar = new CBRegistrar();
callbackRegistrar.Completed += SomeFunc;
Callback functions are not much used in C#. They've been replaced by events which are more elegant and easier to work with.
class CBRegistrar
{
public delegate void ActionRequiredEventHandler(object sender, ISomeClass e);
public event ActionRequiredEventHandler ActionRequired;
void RaiseActionRequiredEvent(ISomeClass parm)
{
if ( ActionRequired != null)
{
ActionRequired(this, parm);
}
}
}
class APIConsumer
{
var callbackRegistrar = new CBRegistrar();
public APIConsumer()
{
callbackRegistrar.ActionRequired += SomeFunc;
}
public void SomeFunc(object sender, ISomeClass data)
{
}
}
If you still want to use Callbacks, you can use Delegates which are more or less function pointer.
The CBRegistrar will need to be generic (if it's OK to keep a single callback type) or it can do some internal casting (if several callback types need to be registered).
public class CBRegistrar<T>
{
private Action<T> callback;
private Dictionary<Type, object> callbackMap;
public CBRegistrar()
{
this.callbackMap = new Dictionary<Type, object>();
}
public void RegisterCallback(Action<T> func)
{
this.callback = func;
}
public void RegisterGenericCallback<U>(Action<U> func)
{
this.callbackMap[typeof(U)] = func;
}
public Action<U> GetCallback<U>()
{
return this.callbackMap[typeof(U)] as Action<U>;
}
}
public interface ISomeClass
{
string GetName();
}
public class SomeClass : ISomeClass
{
public string GetName()
{
return this.GetType().Name;
}
}
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var callbackRegistrar = new CBRegistrar<ISomeClass>();
callbackRegistrar.RegisterCallback(SomeFunc);
callbackRegistrar.RegisterGenericCallback<ISomeClass>(SomeFunc);
var someone = new SomeClass();
callbackRegistrar.GetCallback<ISomeClass>()(someone);
}
public static void SomeFunc(ISomeClass data)
{
// Do something
Console.WriteLine(data.GetName());
}
}
}
class Program
{
static void Main(string[] args)
{
List<A> myList = new List<A> {new A(), new B(), new C()};
foreach (var a in myList)
{
Render(a);
}
Console.ReadKey();
}
private static void Render(A o)
{
Console.Write("A");
}
private static void Render(B b)
{
Console.Write("B");
}
private static void Render(C c)
{
Console.Write("C");
}
}
class A
{
}
class B : A
{
}
class C : A
{
}
The output is: AAA
Is it possible to somehow use method overloading, so that the output would be: ABC?
You can use dynamic typing if you're using C# 4:
foreach (dynamic a in myList)
{
Render(a);
}
Within static typing, overload resolution is performed at compile-time, not at execution time.
For the implementation to be chosen at decision time, you either have to use overriding instead of overloading, or use dynamic typing as above.
The following ought to do the trick, where we control the behaviour when working with a type within that type:
class A
{
public virtual void Render()
{
Console.WriteLine("A");
}
}
class B : A
{
public override void Render()
{
Console.WriteLine("B");
}
}
class C : A
{
public override void Render()
{
Console.WriteLine("C");
}
}
static void Main(string[] args)
{
var myList = new List<A> { new A(), new B(), new C() };
foreach (var a in myList)
{
a.Render();
}
Console.ReadKey();
}
And if you want the defined behaviour of a type to be additive to that of its parent, then call the method implemented in the base after executing your own logic, for example:
class B : A
{
public override void Render()
{
Console.WriteLine("B");
base.Render();
}
}
Another way to accomplish this is with the visitor pattern: it allows you to achieve something like polymorphism using a two-way method calling system:
interface IRenderable
{
AcceptForRender(Program renderer);
}
class Program
{
static void Main(string[] args)
{
var p = new Program();
var myList = new List<IRenderable> {new A(), new B(), new C()};
foreach (var a in myList)
{
a.AcceptForRender(p);
}
Console.ReadKey();
}
public void Render(A o)
{
Console.Write("A");
}
public void Render(B b)
{
Console.Write("B");
}
public void Render(C c)
{
Console.Write("C");
}
}
class A : IRenderable
{
public void AcceptForRender(Program renderer)
{
renderer.Render(this);
}
}
class B : IRenderable
{
public void AcceptForRender(Program renderer)
{
renderer.Render(this);
}
}
class C : IRenderable
{
public void AcceptForRender(Program renderer)
{
renderer.Render(this);
}
}
The advantage to this approach is that it allows you to effectively achieve polymorphism (each type ensures the correct overload is called by passing the strongly-typed this to Render internally) while keeping logic that does not belong in your types themselves (e.g., visual rendering logic) out.
Make A B C deriving from a base ( abstract ) class, define in that class a method Render and override properly in each A B C . Instead of calling Render(a) then call a.Render() this is the way polymorfism is supposed to work.