Anonymous inner classes in C# - c#

I'm in the process of writing a C# Wicket implementation in order to deepen my understanding of C# and Wicket. One of the issues we're running into is that Wicket makes heavy use of anonymous inner classes, and C# has no anonymous inner classes.
So, for example, in Wicket, you define a Link like this:
Link link = new Link("id") {
#Override
void onClick() {
setResponsePage(...);
}
};
Since Link is an abstract class, it forces the implementor to implement an onClick method.
However, in C#, since there are no anonymous inner classes, there is no way to do this. As an alternative, you could use events like this:
var link = new Link("id");
link.Click += (sender, eventArgs) => setResponsePage(...);
Of course, there are a couple of drawbacks with this. First of all, there can be multiple Click handlers, which might not be cool. It also does not force the implementor to add a Click handler.
Another option might be to just have a closure property like this:
var link = new Link("id");
link.Click = () => setResponsePage(...);
This solves the problem of having many handlers, but still doesn't force the implementor to add the handler.
So, my question is, how do you emulate something like this in idiomatic C#?

You can make the delegate be part of the constructor of the Link class. This way the user will have to add it.
public class Link
{
public Link(string id, Action handleStuff)
{
...
}
}
Then you create an instance this way:
var link = new Link("id", () => do stuff);

This is what I would do:
Retain Link as an abstract class, use a Factory to instantiate it and pass in your closure / anonymous method as a parameter for the Factory's build method. This way, you can keep your original design with Link as an abstract class, forcing implementation through the factory, and still hiding any concrete trace of Link inside the factory.
Here is some example code:
class Program
{
static void Main(string[] args)
{
Link link = LinkFactory.GetLink("id", () =>
// This would be your onClick method.
{
// SetResponsePage(...);
Console.WriteLine("Clicked");
Console.ReadLine();
});
link.FireOnClick();
}
public static class LinkFactory
{
private class DerivedLink : Link
{
internal DerivedLink(String id, Action action)
{
this.ID = id;
this.OnClick = action;
}
}
public static Link GetLink(String id, Action onClick)
{
return new DerivedLink(id, onClick);
}
}
public abstract class Link
{
public void FireOnClick()
{
OnClick();
}
public String ID
{
get;
set;
}
public Action OnClick
{
get;
set;
}
}
}
EDIT: Actually, This may be a little closer to what you want:
Link link = new Link.Builder
{
OnClick = () =>
{
// SetResponsePage(...);
},
OnFoo = () =>
{
// Foo!
}
}.Build("id");
The beauty is it uses an init block, allowing you to declare as many optional implementations of actions within the Link class as you want.
Here's the relevant Link class (With sealed Builder inner class).
public class Link
{
public sealed class Builder
{
public Action OnClick;
public Action OnFoo;
public Link Build(String ID)
{
Link link = new Link(ID);
link.OnClick = this.OnClick;
link.OnFoo = this.OnFoo;
return link;
}
}
public Action OnClick;
public Action OnFoo;
public String ID
{
get;
set;
}
private Link(String ID)
{
this.ID = ID;
}
}
This is close to what you're looking for, but I think we can take it a step further with optional named arguments, a C# 4.0 feature. Let's look at the example declaration of Link with optional named arguments:
Link link = Link.Builder.Build("id",
OnClick: () =>
{
// SetResponsePage(...);
Console.WriteLine("Click!");
},
OnFoo: () =>
{
Console.WriteLine("Foo!");
Console.ReadLine();
}
);
Why is this cool? Let's look at the new Link class:
public class Link
{
public static class Builder
{
private static Action DefaultAction = () => Console.WriteLine("Action not set.");
public static Link Build(String ID, Action OnClick = null, Action OnFoo = null, Action OnBar = null)
{
return new Link(ID, OnClick == null ? DefaultAction : OnClick, OnFoo == null ? DefaultAction : OnFoo, OnBar == null ? DefaultAction : OnBar);
}
}
public Action OnClick;
public Action OnFoo;
public Action OnBar;
public String ID
{
get;
set;
}
private Link(String ID, Action Click, Action Foo, Action Bar)
{
this.ID = ID;
this.OnClick = Click;
this.OnFoo = Foo;
this.OnBar = Bar;
}
}
Inside the static class Builder, there is a factory method Build that takes in 1 required parameter (The ID) and 3 optional parameters, OnClick, OnFoo and OnBar. If they are not assigned, the factory method gives them a default implementation.
So in your constructor's parameter arguments for Link, you are only required to implement the methods that you need, otherwise they will use the default action, which could be nothing.
The drawback, however, is in the final example, the Link class is not abstract. But it cannot be instantiated outside of the scope of the Link class, because its constructor is private (Forcing the usage of the Builder class to instantiate Link).
You could also move the optional parameters into Link's constructor directly, avoiding the need for a factory altogether.

I started this before #meatthew's good answer - I would do almost exactly the same except - except that I would start with an abstract base class - so that if you did not want to go the route of an anonymous implementation you would be free to do that too.
public abstract class LinkBase
{
public abstract string Name { get; }
protected abstract void OnClick(object sender, EventArgs eventArgs);
//...
}
public class Link : LinkBase
{
public Link(string name, Action<object, EventArgs> onClick)
{
_name = Name;
_onClick = onClick;
}
public override string Name
{
get { return _name; }
}
protected override void OnClick(object sender, EventArgs eventArgs)
{
if (_onClick != null)
{
_onClick(sender, eventArgs);
}
}
private readonly string _name;
private readonly Action<object, EventArgs> _onClick;
}

Related

Setting action from function parameter is null

I have some actions in a view.
public class AView
{
public Action Show { get; set; }
public Action Hide { get; set; }
}
and I'm trying to set those actions inside another class, by passing them as a parameter (I don't want to pass the whole class)
_reloader.SetupActions(Show, Hide);
Reloader is abstract, because there might be different ways of handling how Hide/Show must behave depending on the scenario we're in.
public abstract class Reloader : IReloader
{
public void SetupActions(Action show, Action hide)
{
show = Show;
hide = Hide;
}
protected virtual void Show() { ... } //what should be done when Show is invoked
protected virtual void Hide() { ... } //same for Hiding
}
And for the current view, I might be using a RapidReloader, SafeReloader, etc. This bit is irrelevant, except that the injected reloader is specific to the current view.
Now my problem is simple and logic : when I'm in SetupActions, all parameters are null (because Actions haven't been set), and setting Show into null obviously does not work.
What can I do so that when Show.Invoke() happens my view, the ShowCode from the relevant reloader is called? I would like to avoid passing the whole view as a parameter.
Also, if you have a better design, I'm all ears. We might be in an XY problem situation
You will need to use System.ValueTuple nuget package if you don't use .Net Framework 4.7 or newer.
public interface IReloader
{
(Action Show, Action Hide) GetActions();
}
public abstract class Reloader : IReloader
{
public (Action Show, Action Hide) GetActions()
{
return (Show, Hide);
}
protected virtual void Show() { }
protected virtual void Hide() { }
}
public class FastReloader : Reloader { }
public class AView
{
public Action Show{ get; set; }
public Action Hide{ get; set; }
public void IwantTheNewActions()
{
var reloader = new FastReloader();
var actions = reloader.GetActions();
Show = actions.Show;
Hide = actions.Hide;
}
}

Event Callback with Strongly Typed Object

I'm trying to get a proof of concept down for a feature I need in my code. In the real application, I have a Dependency Injection container, and children sometimes need to 'new up' an object, and I need the DI container to return that object. So I'm using an event with a callback that lets the child get that instatiated object.
The problem is, I'd like one event, but allow it to return whichever object the caller specifies. I'm not sure how to get that strongly typed object back (without casting). I feel like it should be possible. If that's confusing enough, here's my example:
class Program
{
public static event EventHandler<MyEventArgs> MyEvent;
public static void Main()
{
MyEvent += (sender, args) =>
{
Console.WriteLine("Event Fired");
args.Callback("hello");
};
MyEvent(null, new MyEventArgs(obj => Console.WriteLine($"How do I get {obj} strongly typed")));
Console.Read();
}
}
and the event args:
public class MyEventArgs
{
public Action<object> Callback { get; set; }
public MyEventArgs(Action<object> callback)
{
Callback = callback;
}
}
I'm stuck, because MyEventArgs can't take a type parameter, as I would really like just one event to handle any return object type. Is it possible to get a strongly typed object through the callback?
Again, I could send the Type through as a parameter, and cast it, but I feel like this should be do-able. It's entirely possible that this is impossible, too.
Thanks for any guidance.
I worked out a solution that is almost exactly what I was going for:
public class MyEventArgs<T> : MyEventArgs where T : class
{
private Action<T> _callback;
public MyEventArgs(Action<T> callback)
{
_callback = callback;
}
public override void DoCallback(object item)
{
_callback(item as T);
}
}
public abstract class MyEventArgs
{
public abstract void DoCallback(object item);
}
and in my Main:
public static event EventHandler<MyEventArgs> MyEvent;
public static void Main()
{
MyEvent += (sender, args) =>
{
Console.WriteLine("Event Fired");
args.DoCallback("hello");
};
MyEvent(null, new MyEventArgs<string>(s => Console.WriteLine($"{s} is a string")));
Console.Read();
}
All it's missing is DoCallback()'s parameter is not strongly typed. But it's exremely close to what I wanted.
You probably would like to take a look at dynamic types.
public class MyEventArgs
{
public Action<dynamic> Callback { get; set; }
public MyEventArgs(Action<dynamic> callback)
{
Callback = callback;
}
}
It will allow you to pass any type to callback.

Refactor long switch statement

I'm program in c# which you controlling by dictating command so now i have a long switch statement. Something like
switch (command)
{
case "Show commands":
ProgramCommans.ShowAllCommands();
break;
case "Close window":
ControlCommands.CloseWindow();
break;
case "Switch window":
ControlCommands.SwitchWindow();
break;
}
and so on
Almost all cases call only one method, methods are not in one class they are distributed in many classes. So the question is, how i could refactor this switch to more elegant way?
You can do this to refactor your switch statement:
var commands = new Dictionary<string, Action>()
{
{ "Show commands", () => ProgramCommans.ShowAllCommands() },
{ "Close window", () => ControlCommands.CloseWindow() },
{ "Switch window", () => ControlCommands.SwitchWindow() },
};
if (commands.ContainsKey(command))
{
commands[command].Invoke();
}
The main advantage to this approach is that you can change the "switch" at run-time.
I much prefer the Strategy Pattern for extending switch case statements. First, I create an interface that defines what each rule should look like:
public interface IWindowRule
{
string Command { get; }
void Invoke();
}
Then create a class that implements the interface for each possible case:
public class ShowAllWindowRule : IWindowRule
{
public string Command => "Show commands";
private ProgramCommands _progCommands;
public ShowAllWindowRule(ProgramCommands programCommands) =>
_progCommands = programCommands;
public void Invoke() => _progCommands.ShowAllCommands();
}
public class CloseWindowRule : IWindowRule
{
private ControlCommands _ctrlCommands;
public string Command => "Close window";
public CloseWindowRule(ControlCommands ctrlCommands) =>
_ctrlCommands = ctrlCommands;
public void Invoke() =>
_ctrlCommands.CloseWindow();
}
public class SwitchWindowRule : IWindowRule
{
private ControlCommands _ctrlCommands;
public string Command => "Switch window";
public SwitchWindowRule(ControlCommands ctrlCommands) =>
_ctrlCommands = ctrlCommands;
public void Invoke() =>
_ctrlCommands.SwitchWindow();
}
Then your switch statement turns into this:
public void RunWindowRule(IList<IWindowRule> rules, string command)
{
foreach (IWindowRule rule in rules)
{
if (rule.Command == command) rule.Invoke();
}
}
Now you can pass the function any set of rules you wish and run them making the function adhere to the Open/Closed principle.
I realize this may appear to be a bit of over engineering, and I do think there are more functional solutions that require a bit less work, however this has the added benefit of allowing you to extend this function by creating classes that inject the list of rules for a myriad of circumstances or even make a builder class that give you a fluent API.
public class WindowRuleBuilder
{
private IList<IWindowRule> rules;
public WindowRuleBuilder(IList<IWindowRule> rules = null) =>
rules = rules ?? new List<IWindowRule>();
public WindowRuleBuilder AddRule(IWindowRule newRule)
{
rules.Add(newRule);
return this;
}
public void Run(string command)
{
foreach (IWindowRule rule in rules)
{
if (rule.Command == command) rule.Invoke();
}
}
}
Now you have something like this:
public static void Main(string[] args)
{
WindowRuleBuilder ruleBuilder = new WindowRuleBuilder()
.AddRule(new CloseWindowRule(conrolCommands))
.AddRule(new ShowAllWindowRule(programCommands))
.AddRule(new SwitchWindowRule(controlCommands));
ruleBuilder.Run(args[0]);
}
This is highly extendable as for ever new rule you simply create the class and add it to the rule builder with the AddRule() method. It also doesn't take much reading to understand what's going on here. It's a much more compositional approach. Though I again admit, it does take a bit of work to implement but the code adheres to SOLID and is finely decoupled.
If all the functions get the same parameters and return the same value, you can use a Dictionary along with delegates to map a string to a function(s). This method will allow you also to change in run time the switch - allowing external programs to extend the functionality of the program.
If the functions aren't the same, you could write wrappers - a proxy function that will get parameters as all other functions, and call the functions you want.
I realize this is an old post, but in these situations I find attributes and a factory very handy.
The following code uses a custom attribute (Command) to allow you to attribute your methods, providing a string value of how they should respond to you.
The factory method uses reflection to generate a dictionary of these methods and calls it whenever you call CommandFactory.
Things could get cleaned up a bit, calling invoke is a little ugly, but it just depends on how you want to execute the code.
using System.Collections.Generic;
using System.Linq;
namespace MyApp
{
using System.Reflection;
using MyApp.Commands;
class Program
{
static void Main(string[] args)
{
var methods = new MyCommands();
MethodInfo myMethod;
myMethod = CommandFactory.GetCommandMethod("Show Commands");
myMethod.Invoke(methods, null);
myMethod = CommandFactory.GetCommandMethod("Close window");
myMethod.Invoke(methods, null);
myMethod = CommandFactory.GetCommandMethod("Switch window");
myMethod.Invoke(methods, null);
}
}
public static class CommandFactory
{
private static Dictionary<string, MethodInfo> speechMethods = new Dictionary<string, MethodInfo>();
public static MethodInfo GetCommandMethod(string commandText)
{
MethodInfo methodInfo;
var commands = new MyCommands();
if (speechMethods.Count == 0)
{
var methodNames =
typeof(MyCommands).GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
var speechAttributeMethods = methodNames.Where(y => y.GetCustomAttributes().OfType<CommandAttribute>().Any());
foreach (var speechAttributeMethod in speechAttributeMethods)
{
foreach (var attribute in speechAttributeMethod.GetCustomAttributes(true))
{
speechMethods.Add(((CommandAttribute)attribute).Command, speechAttributeMethod);
}
}
methodInfo = speechMethods[commandText];
}
else
{
methodInfo = speechMethods[commandText];
}
return methodInfo;
}
}
}
namespace MyApp.Commands
{
class MyCommands
{
[Command("Show All")]
[Command("Show All Commands")]
[Command("Show commands")]
public void ShowAll()
{
ProgramCommands.ShowAllCommands();
}
[Command("Close Window")]
public void CloseWindow()
{
ControlCommands.CloseWindow();
}
[Command("Switch Window")]
public void SwitchWindow()
{
ControlCommands.SwitchWindow();
}
}
[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = true)]
public class CommandAttribute : System.Attribute
{
public string Command
{
get;
set;
}
public CommandAttribute(string textValue)
{
this.Command = textValue;
}
}
}
I know the answer is a bit late, to not abuse the SOLID principle, you may use interface or inheritance. In this example, I use inheritance because u may have other usages of "command" string.
public abstract class commandRepository {
string command ; // if there is no usage in other function class, you can get rid of it
public abstract void DoCommands();
}
public class ShowCommands:commandRepository
{
public ShowCommands (){
command ="Show commands"; // if there is no usage in other function class, you can get rid of it
}
public override void DoCommands(){
ProgramCommans.ShowAllCommands();
}
}
public class CloseWindow:commandRepository
{
public CloseWindow (){
command ="Close window"; // if there is no usage in other function class, you can get rid of it
}
public override void DoCommands(){
ProgramCommans.CloseWindow();
}
}
public class SwitchWindow:commandRepository
{
public SwitchWindow (){
command ="Switch window"; // if there is no usage in other function class, you can get rid of it
}
public override void DoCommands(){
ProgramCommans.SwitchWindow();
}
}
Here's what you can do here. You can create an interface [ICommand] where you can place a common function [eg: Execute].
Then you just needs to initiate that member with appropriate type and call the Execute function. This might include more functions in the future and is thus extended.
Also, you can create a factory method where you can pass the parameter and get the appropriate class to work with.
Hope that helps.

Save actions or funcs on secondary memory

I am creating a program where the user creates custom commands and execute them when needed. as a result I have a class similar to:
public class Command
{
Action c { get; set; }
// Overloaded Constructors------------------------------------
// changes the volume
public Command(int volumeChange)
{
c = ()=>
SomeClass.ChangeMasterVolume(volumeChange);
}
// Animate something
public Command(int x, int y)
{
c = ()=>
SomeClass.MoveMouse(x,y);
}
// etc.. there are more contructors....
//---------------------------------------------------------
public void ExecuteCommand()
{
c();
}
}
When the user closes the application I will like to save those commands somewhere on disk. There are about 200 different commands and it will be nice if I could serialize an instance from that class. Since it contains an Action it is not possible to serialize it.
It will be nice if I don't have to create a huge switch statement in order to determine what command to execute. What is the best way of dealing with this?
Sounds to me like you simply need to keep an interface around instead of a delegate.
public interface IDoThingy
{
void DoStuff();
}
public class IncreaseVolumeThingy : IDoThingy
{
public int Volume { get; set; }
public IncreaseVolumeThingy(int volume)
{
Volume = volume;
}
public void DoStuff()
{
SomeClass.ChangeMasterVolume(Volume);
}
}
public class Command
{
protected IDoThingy _thingy = null;
public Command(IDoThingy thingy)
{
_thingy = thingy;
}
public void ExecuteCommand()
{
_thingy.DoStuff();
}
}
So instead of creating a set of constructors, you simply make some form of factory based on the command specified. If the user is setting up a Increase volume command, then you new an instance of the IncreaseVolumeThingy and store it. When it is serialized, it can be recreated from state without a delegate.
Use reflection to call a class method by its name. Serialize the class and method name.
http://www.codeproject.com/Articles/19911/Dynamically-Invoke-A-Method-Given-Strings-with-Met

How to stop base static events/actions firing in other derived classes

I am working on an LOB application in C# using a WinForms tabbed MDI interface. I have various forms with DataGridViews to allow the user to select an object they are interested in, which they can then view/edit in a new form.
Each of my main business objects inherit from Entity, which is defined as below:
public abstract class Entity
{
public static event Action Saved;
internal virtual void OnSaved()
{
if (Saved != null)
{
Saved();
}
}
}
I then have the objects that populate the grid (these are actually auto-generated classes from Linq-to-SQL, although I can replicate the problem with normal classes):
class Class1 : Entity
{
//Stuff
}
class Class2 : Entity
{
//Stuff
}
I want to know when an object of a given class is modified, but i don't care which instance (hence the static action) so that i can refresh the grid and perform other activities.
The problem comes when the event is fired from a derived class instance - it fires for all other derived classes too. For example:
Class1.Saved += new Action(s1);
Class2.Saved += new Action(s2);
private void TestIt()
{
Class2 o2 = new Class2();
o2.OnSaved();
}
This would fire s1 and s2, but I only want the specific one to be fired (i.e. s2). What is the best way to do this? I have quite a few classes that need this behviour and would like to avoid having to add any code to each class if possible.
Update:
Thank you for all your responses, they have been very helpful.
I have opted for a slightly different option, which I admit seems quite hacky, but works well for my purposes. This involves passing the type with the action and letting a handler filter and call relevant operations.
Entity Class:
public abstract class Entity
{
public static event Action<Type> Saved;
internal void OnSaved()
{
private Action<Type> SavedCopy = Saved;
if (SavedCopy != null)
SavedCopy(this.GetType());
}
}
Hook up handler:
Entity.Saved += new Action<Type>(Handler);
Example Handler method (this will vary from form to form):
void Handler(Type obj)
{
if (obj==typeof(Class1))
UpdateGrid();
else if (obj==typeof(Class2))
UpdateBasicInfo();
else if (obj == typeof(Class3))
DoAnotherThing();
}
Using generics could be a work around; each generic class gets a copy of the static fields.
public abstract class Entity<T>
{
public static event Action Saved = delegate { };
internal virtual void OnSaved()
{
Saved();
}
}
class Class1 : Entity<Class1>
{
//Stuff
}
class Class2 : Entity<Class2>
{
//Stuff
}
I'm not sure doing it like this is a good idea, but you could specify the type when you subscribe and when you save the data:
public abstract class Entity
{
private static Dictionary<Type, Action> Subscribers
= new Dictionary<Type, Action>();
internal virtual void OnSaved()
{
OnSaved(GetType());
}
private OnSaved(Type type)
{
Action subscribed;
Subscribers.TryGetValue(type, out subscribed);
if (subscribed != null)
subscribed();
}
public Subscribe(Type type, Action action)
{
Action subscribed;
Subscribers.TryGetValue(type, out subscribed);
Subscribers[type] = subscribed + action;
}
public Unsubscribe(Type type, Action action)
{
Action subscribed;
Subscribers.TryGetValue(type, out subscribed);
Subscribers[type] = subscribed - action;
}
}
Keep in mind that this code is not thread-safe, so if you want to use it from different threads at the same time, you need to add locking.
You will need to have an event per type, because can't determine for which type the delegate is registered when the event is defined on the base type.
public abstract class Entity
{
internal abstract void OnSaved();
}
class Class1 : Entity
{
public static event Action Saved = () => { };
internal override void OnSaved()
{
this.Saved();
}
//Stuff
}
class Class2 : Entity
{
public static event Action Saved = () => { };
internal override void OnSaved()
{
this.Saved();
}
//Stuff
}
Why does it have to be static? Make it an instance event instead.
public event Action Saved;
You have to hook it up for each instance instead of just once per class (or, in your current case, once), but it will separate the events.

Categories