Lambda implementing Interface - c#

In the book I'm reading "Head First Design Patterns", Command Pattern there is an example where they're substituting an Interface with Lambda.
Is this something that only Java is capable of?
Here is an example
From the book:
// Receiver
public class Light
{
public void On() {
Console.WriteLine("Lights on");
}
public void Off() {
Console.WriteLine("Ligts off");
}
}
// Command interface
public interface ICommand
{
void Execute();
}
// Concrete command
public class SimpleCommandLightOn : ICommand
{
private readonly Light light;
public SimpleCommandLightOn(Light light) {
this.light = light;
}
public void Execute() {
light.On();
}
}
// Concrete command
public class SimpleCommandLightOff : ICommand
{
private readonly Light light;
public SimpleCommandLightOff(Light light)
{
this.light = light;
}
public void Execute()
{
light.Off();
}
}
// Invoker
public class SimpleRemoteControl
{
private ICommand command;
public void SetCommand(ICommand command) {
this.command = command;
}
public void OnButtonPress() {
command.Execute();
}
// OffCommand needs to be set
public void OffButtonPress() {
command.Execute();
}
}
In the book they're stating that this is possible:
Light light = new Light();
remote.SetCommand(() => light.On());
However c# throws an error. Is this no the case when working with C#?

This does not work because in C#, lambda expressions map to delegates - a concept that does not exist in Java. Java has had a lot of these one-method interfaces for a long time before they finally introduced lambdas in Java 8. Given this and the lack of delegates, it was more or less natural to associate lambdas wit these one-method interfaces. C# / .NET, on the other hand, had delegates from the beginning and used them at many places where you would find a one-method interface in Java. Compare e.g. Observer and EventHandler.
So in a .NET API, you would consider using a delegate type like Action instead of ICommand, and then you would be able to use a lambda with it.
It should also be noted that .NET does have one-method interfaces, too. Some basic guidance about when to choose an interface or a delegate can be found at MSDN.

Matthias' answer is great, let me just add how a C# idiomatic way of declaring a command would look like:
delegate void Command();
That's it (though nowadays, you'd just use the generic Action delegate rather than defining your own). Your method would be
public void SetCommand(Command command)
{
this.command = command;
}
and invoking the command is as simple as
command();
Calling the SetCommand method can look like this:
SetCommand(() => DoSomething()); // Lambda
SetCommand(delegate () { DoSomething(); }); // Anonymous method
SetCommand(Someone.DoSomething); // Named method - Someone can be a type or an instance
As you can see, there's little point in using an interface for something a simple delegate can do. Java uses the syntax it does because it never supported delegates, and because it supports anonymous interface implementations - something C# doesn't have.
As an added bonus, delegates natively support chains - so a delegate can represent a set of delegates that are to be executed in a sequence. This is mostly used in events - another syntax helper that makes your job a little bit easier, with the handy syntax of SomeEvent += someDelegate; to register an event handler.

As an alternative, one can create an implementation of the interface that passes the calls through to lambda expressions.
public interface ICommand
{
void Execute();
int Calculate(int input);
}
public class LambdaCommand : ICommand
{
readonly Action execute;
readonly Func<int, int> calculate;
public LambdaCommand(Action execute, Func<int, int> calculate)
{
this.execute = execute;
this.calculate = calculate;
}
public void Execute() => execute();
public int Calculate() => calculate();
}
...
remote.SetCommand(new LambdaCommand(() => light.On(), _ => _));

Related

Interface covariance contravariance : why is this not compiling?

I want to implement a CommandBus that can Dispatch some Commands to CommandHandlers.
A Command is a simple a DTO describing what should happen. For instance : "Increment counter by 5"
A CommandHandler is able to handle a precise type of Command.
The CommandBus takes a Command and executes the CommandHandler that is able to handle it.
The code I wrote does not compile.
Compiler complains cannot convert from 'IncrementHandler' to 'Handler<Command>'.
I don't understand why, because IncrementHandler implements Handler<Increment> and Increment implements Command
I've tried both in and out modifiers on the generic interfaces, it doesn't solve the problem.
Is there a way to achieve this with only interfaces ?
[TestClass]
public class CommandBusTest
{
[TestMethod]
public void DispatchesProperly()
{
var handler = new IncrementHandler(counter: 0);
var bus = new CommandBus(handler); // <--Doesn't compile: cannot convert from 'IncrementHandler' to 'Handler<Command>'
bus.Dispatch(new Increment(5));
Assert.AreEqual(5, handler.Counter);
}
}
public class CommandBus
{
private readonly Dictionary<Type, Handler<Command>> handlers;
public CommandBus(params Handler<Command>[] handlers)
{
this.handlers = handlers.ToDictionary(
h => h.HandledCommand,
h => h);
}
public void Dispatch(Command commande) { /*...*/ }
}
public interface Command { }
public interface Handler<TCommand> where TCommand : Command
{
Type HandledCommand { get; }
void Handle(TCommand command);
}
public class Increment : Command
{
public Increment(int value) { Value = value; }
public int Value { get; }
}
public class IncrementHandler : Handler<Increment>
{
// Handler<Increment>
public Type HandledCommand => typeof(Increment);
public void Handle(Increment command)
{
Counter += command.Value;
}
// Handler<Increment>
public int Counter { get; private set; }
public IncrementHandler(int counter)
{
Counter = counter;
}
}
I don't understand why, because IncrementHandler implements Handler<Increment> and Increment implements Command
Let's fix your misunderstanding, and then the rest will become clear.
Suppose what you wanted to do was legal. What goes wrong?
IncrementHandler ih = whatever;
Handler<Command> h = ih; // This is illegal. Suppose it is legal.
now we make a class
public class Decrement : Command { ... }
And now we pass it to h:
Decrement d = new Decrement();
h.Handle(d);
This is legal, because Handler<Command>.Handle takes a Command, and a Decrement is a Command.
So what happened? You just passed a decrement command to ih, via h, but ih is an IncrementHandler that only knows how to handle increments.
Since that is nonsensical, something in here has to be illegal; which line would you like to be illegal? The C# team decided that the conversion is the thing that should be illegal.
More specifically:
Your program is using reflection in an attempted end-run around the type system's safety checks, and then you are complaining that the type system is stopping you when you write something unsafe. Why are you using generics at all?
Generics are (in part) to ensure type safety, and then you are doing a dispatch based on reflection. This doesn't make any sense; don't take steps to increase type safety and then do heroic efforts to work around them.
Plainly you wish to work around type safety, so don't use generics at all. Just make an ICommand interface and a Handler class that takes a command, and then have some mechanism for working out how to dispatch commands.
What I don't understand though is why there are two kinds of things at all. If you want to execute a command, then why not simply put the execution logic on the command object?
There are also other design patterns you could use here other than this clunky dictionary lookup based on types. For example:
a command handler could have a method that takes a command and returns a boolean, whether the handler can handle this command or not. Now you have a list of command handlers, a command comes in, and you just run down the list asking "are you my handler?" until you find one. If O(n) lookup is too slow, then build a MRU cache or memoize the result or some such thing, and the amortized behaviour will improve.
the dispatch logic could be put into the command handler itself. A command handler is given a command; it either executes it, or it recurses, calling its parent command handler. You can thus build a graph of command handlers that defer work to each other as necessary. (This is basically how QueryService works in COM.)
The problem here is that Increment implements Command (which I renamed to ICommand to make that clearer, in the code below).
So it is no longer accepted as a Handler<Command>, which is what the constructor expects (subtype instead of required supertype, as #Lee pointed out in comments).
If you can generalize to use just ICommand, it would work:
public class CommandBusTest
{
public void DispatchesProperly()
{
var handler = new IncrementHandler(counter: 0);
var bus = new CommandBus((IHandler<ICommand>)handler);
bus.Dispatch(new Increment(5));
}
}
public class CommandBus
{
private readonly Dictionary<Type, IHandler<ICommand>> handlers;
public CommandBus(params IHandler<ICommand>[] handlers)
{
this.handlers = handlers.ToDictionary(
h => h.HandledCommand,
h => h);
}
public void Dispatch(ICommand commande) { /*...*/ }
}
public interface ICommand { int Value { get; } }
public interface IHandler<TCommand> where TCommand : ICommand
{
Type HandledCommand { get; }
void Handle(TCommand command);
}
public class Increment : ICommand
{
public Increment(int value) { Value = value; }
public int Value { get; }
}
public class IncrementHandler : IHandler<ICommand>
{
// Handler<ICommand>
public Type HandledCommand => typeof(Increment);
public void Handle(ICommand command)
{
Counter += command.Value;
}
// Handler<ICommand>
public int Counter { get; private set; }
public IncrementHandler(int counter)
{
Counter = counter;
}
}
The problem here is that your definition of Handler<TCommand> requires TCommand to be both covariant and contravariant - and that's not allowed.
To pass a Handler<Increment> into the constructor of CommandBus (which expects a Handler<Command>), you must declare Command as a covariant type parameter in Handler, like this:
public interface Handler<out TCommand> where TCommand : Command
Making this change allows you to pass in a Handler<AnythingThatImplementsCommand> wherever a Handler<Command> is requested, so your constructor for CommandBus works now.
But this introduces a new issue for the following line:
void Handle(TCommand command);
Since TCommand is covariant, it is possible to assign a Handler<Increment> to a Handler<Command> reference. Then you would be able to call the Handle method but pass in anything that implements Command - clearly that's not going to work. To make this call correct, you have to allow TCommand to be contravariant instead.
Since you can't do both, you'll have to make a concession somewhere. One way to do this is by making using covariance in Handler<TCommand>, but force an explicit cast in your Handle method, like this:
public interface Handler<out TCommand> where TCommand : Command
{
Type HandledCommand { get; }
void Handle(Command command);
}
public class IncrementHandler : Handler<Increment>
{
public void Handle(Command command)
{
Counter += ((Increment)command).Value;
}
}
It doesn't prevent somebody from creating an IncrementHandler and then passing in the wrong kind of Command, but if the handlers are only used by CommandBus you can check the type in CommandBus.Dispatch and have something resembling type safety.

Using an interface from class in C# [duplicate]

This question already has answers here:
Counterpart to anonymous interface implementations in C#
(5 answers)
Closed 5 years ago.
I have a class that has an interface in it like so:
public class hcmTerminal {
... Code
public interface onDataReceived {
void isCompleted(bool done);
}
}
inside this class I I have the public property:
public onDataReceived mDataReceived;
then I have a function to set the delegate:
public void setDataReceived(onDataReceived dataReceived) { mDataReceived = dataReceived; }
Inside the hcmTerminal class I am am calling the delegate :
mDataReceived.isCompleted(true);
But I can't figure out the syntax to actually get when that delegate gets called, In java I can go:
myTerminal.setDataReceived(new hcmTerminal.onDataReceived(){
#Override
public void isCompleted(boolean done){
... Code
}
});
But if I try that in C# I get:
Cannot create an instance of the abstract or interface
'hcmTerminal.onDataReceived'
I haven't had to create a interface in C# before. this code is coming from how I implemented it in Java.
By using events you can accomplish that by
class HcmTerminal {
public event Action<bool> OnDataReceived;
public void Launch()
{
OnDataReceived?.Invoke(true /*or false*/);
}
}
You can then do:
var myTerminal = new HcmTerminal();
myTerminal.OnDataReceived += (isCompleted) => {};
Define a class implementing the interface:
class MyDataReceived : hcmTerminal.onDataReceived {
public void isCompleted(bool done) {
Console.WriteLine("call to isCompleted. done={0}", done);
}
}
Now you can call myTerminal.setDataReceived(new MyDataReceived())
However, this is a Java solution coded in C#, not a "native" C# solution. A better approach is to define a delegate in place of an interface:
public class HcmTerminal {
... Code
public delegate void OnDataReceived(bool done);
}
This would let you use multiple C# features for supplying delegate implementation, such as providing a method name, supplying an anonymous delegate, or using a lambda:
myTerminal.setDataReceived((done) => {
Console.WriteLine("call to isCompleted. done={0}", done);
});

Reactive Extensions: Allowing only a single subscriber for each type

Is there a way to ensure that there can be at most one subscriber registered per type for a generic type? An example would explain it better:
public interface Message
{
}
public class Command : Message
{
}
public class Event : Message
{
}
public class Bus
{
private readonly IObservable<Message> _stream;
private readonly Subject<Message> _subject;
public Bus()
{
_subject = new Subject<Message>();
_stream = _subject.AsObservable();
}
public IDisposable Subscribe<T>(IObserver<T> observer) where T:Command
{
return _stream.OfType<T>().Subscribe(observer);
}
public void Execute<T>(T command) where T:Command
{
_subject.OnNext(command);
}
}
I'd like to ensure that more than one observer cannot subscribe to the same type of Command. Is there something in Rx that allows that, or am I limited to:
a) Keep a lookup of types myself or
b) Not deal with it during registration, and use an interim subscriber to detect multiple registrations?
I do not think that Rx provides any built in mechanisms for this. Given your example code, I'd just make a Dictionary<Type, IObserver<T>> and use it within your Subscribe method to enforce your constraint.

Passing the Class Type instead of the Interface through Generics

OK I've just implemented a Command-CommandHandler pattern in our application that adds a command object to a queue; then uses dependency injection through Castle Windsor alongside a generic method to get the relevant handler for the command object.
The Command interface is blank like so:
public interface ICommand
{
}
Whilst the CommandHandler interface handles it like so:
public interface ICommandHandler<TCommand> where TCommand : ICommand
{
void Handle(TCommand command);
}
These are then implemented by the commands I wish to send through the queue; then registered in Castle Windsor through a DependencyRegistration wrapper like so:
_dependencyRegister
.AddRegistration<ICommandHandler<TestCommand>, TestCommandHandler>();
So each command that will be added to the queue maps 1 to 1 with a handler; then is registered in Castle Windsor; so we can use a generic method like this to get the relevant CommandHandler for a particular Command object:
private void HandleCommand<T>(T queueItem) where T: ICommand
{
var handler = _dependencyResolver.Resolve<ICommandHandler<T>>();
handler.Handle(queueItem);
}
The final piece is the queue dispatcher method which looks like this:
private void DispatchQueueItem(ICommand queueItem)
{
HandleCommand(queueItem);
}
Right; the issue is that when I pull a command off the queue as an ICommand and pass it to the DispatchQueueItem method; when it is sent to the HandleCommand method the "T" type is always set to the "ICommand" interface; rather than the actual implementation of the interface (TestCommand in the DependencyRegistration sample code).
My question is; how do I set the HandleCommand method to take the Type of the implementation; not the interface?
Change your dispatch method to generic:
private void DispatchQueueItem<T>(T queueItem)
where T: ICommand
{
HandleCommand(queueItem);
}
UPDATE you can force C# to define object type at runtime this way
private static void DispatchQueueItem(ICommand queueItem)
{
HandleCommand((dynamic)queueItem);
}
I think you want it to be of the interface - but you just need to have a method contract defined in there - like:
public interface ICommand
{
void Execute();
}
//Concrete implementation:
public TestCommand : ICommand
{
public void Execute()
{
//Do something
}
}
Then, when you get the ICommand out of DI - you can call queueItem.Execute() - and this will refer to whatever concrete implementation you've assigned.
Yout queue will lalways dispatch ICommands. So so need to get the type "under the hood":
private void HandleCommand<T>(T queueItem) where T: ICommand
{
var typeParam = queueItem.GetType();
var type = typeof(ICommandHandler<>).MakeGenericType(typeParam);
var handler = _dependencyResolver.Resolve(type);
I'm not sure of the exact sintax. Don't have a project with Castle Windsor at hand.

Using Generics in c# in order to avoid code duplication

(Language is c# with VS 2008)
I have the following problem:
There are a number of structs (provided as is from 3rd party) that all implement certain methods with the same signatures.
I would like to wrap these struct with wrapper classes that implement a certain interface so that these classes can be treated in a uniform way.
Example:
interface AnInterface
{
void DoSomething();
}
struct Struct1
{
public void DoSomething();
}
class Struct1Wrapper : AnInterface
{
private Struct1 m_struct;
public override void DoSomething() // AnInterface implementation
{
m_struct.DoSomething();
}
}
Note that Struct1 DoSomething method is concrete while Struct1Wrapper implements it through an interface for easier handling.
The same goes with Struct2 and so on - the code of StructXWrapper is the same except for Struct1 replaced by StructX
I have tried using generics in order to avoid code duplication:
class GenericStructWrapper<AStruct> : AnInterface
{
private AStruct m_struct;
public override void DoSomething() // AnInterface implementation
{
m_struct.DoSomething();
}
}
But this won't work since the compiler doesn't have a notion about AStruct DoSomething() method.
Any other idea how to implement this without duplicating the code of Struct1Wrapper?
Perhaps there is some macro-like feature or some use of reflection?
Thanks,
Ury Jamshy.
You can take a Action<AStruct> in the class constructor that takes the method.
You can then create instances like new GenericStructWrapper<Struct1>(s => s.DoSomething())
C# doesn't safely support structural typing (except in certain unusual contexts), so there's no way to make this completely safe without code-duplication. You either have to go with SLak's technique of asking the client to provide a delegate (will probably involve repeating the same lambda expression over and over) or to assume that the underlying types will satisfy the contract of containing a public void DoSomething() method.
Going with the second option, here's one way using dynamic in C# 4:
public class StructWrapper: AnInterface
{
private readonly dynamic m_struct;
public StructWrapper(object myStruct)
{
m_struct = myStruct;
}
public void DoSomething()
{
m_struct.DoSomething();
}
}
Now, you could try to make this class generic, with the underlying-structure type being the generic-type argument, but that will probably not help you all that much unless you also want to perform structure-specific operations on the wrapped-type. Here's an example of that, with reflection and delegates (C# 3 compatible):
public class StructWrapper<T> : AnInterface where T : struct
{
private readonly Action action;
// deliberately exposed
public T UnderlyingStruct { get; private set; }
public StructWrapper(T underlyingStruct)
{
UnderlyingStruct = underlyingStruct;
action = (Action)Delegate.CreateDelegate
(typeof(Action), underlyingStruct, "DoSomething");
}
public void DoSomething()
{
action();
}
}
Note that you can mix and match the two techniques mentioned above, e.g. reflection but without generics.
Usage:
AnInterface wrapper1 = new StructWrapper(new Struct1());
wrapper1.DoSomething();
StructWrapper<Struct1> wrapper2 = new StructWrapper<Struct1>(new Struct1());
wrapper2.DoSomething();
Struct1 s = wrapper2.UnderlyingStruct; // generics help here
s.SomeOtherMethod();
There is a syntax for this:
class GenericStructWrapper<AStruct> : AnInterface where AStruct : AnInterface
{
private AStruct m_struct;
public override void DoSomething() // AnInterface implementation
{
m_struct.DoSomething();
}
}
This says that AStruct must implement AnInterface

Categories

Resources