Reputation: 6117
I often find it quite a distraction to have to implement an interface just because I need it once for some method call. I have to create a class somewhere else, implement the interface etc. etc.
Java has a feature called Anonymous Classes that allows one to implement the interface "inline". My question is thus: what is the nicest way you can think of of accomplishing something similar in C# using existing syntax (and I realise that "nicest" is subjective). I'm looking for nice syntax, not necessarily performance.
I implemented the following as POC in C#:
Given
interface IFoobar
{
Boolean Foobar(String s);
}
IFoobar foo = Implement.Interface<IFoobar>(new {
Foobar = new Func<String, Boolean>(s => s == "foobar")
});
This uses an anonymous object and some reflection/emit to implement the IFoobar
interface (overlooking properties, generic methods and overloading). But, I'm not a fan of the new Func<...>
stuff but can't do without.
Looking around I noticed a library called Impromptu Interface, but wasn't impressed by its syntax to support methods.
Is there a "nicer" way?
Edit: I'm not looking for Java vs C# flame wars.
Upvotes: 20
Views: 21382
Reputation: 7009
If your biggest complaint is implementing the interface somewhere else, why not create a nested class directly before/after your method? (Compare to a Java static nested class.)
That's more idiomatic C# than creating/using some dynamic framework.
Upvotes: 1
Reputation: 39386
A good way to do what you need in C# could be using Clay objects:
public interface IFoobar{
Func<string, bool> Foobar { get; set; }
}
With that interface you can do something like this:
dynamic New = new ClayFactory();
var foobar= New.FooBar();
foobar.Foobar = new Func<string, bool>(s => s == "foobar");
// Concrete interface implementation gets magically created!
IFoobar lou = foobar;
var result =lou.Foobar("foo");// return false
What makes the magic possible is that Clay
is overriding the cast operator and creating a dynamic proxy for the interface (using Castle
) that delegates the members to the Clay object.
Another way could be using the Impromptu Interface library which lets you wrap any object with an interface. That means any objects now can have dynamic behaviors. If an object has interface methods, you can directly attach behaviors to them as needed. If an object does not have interface methods, you define an interface and wrap the object in it, then, attach behaviors to the interface methods as needed.This library is an automatic way of applying the Object Adapter pattern.
If you have an interface like this:
public Interface IFoobar
{
bool Foobar(string s);
}
You can decorate an anonymous type as I show below:
//Anonymous Class
var anon = new {Foobar= Return<bool>.Arguments<string>(s => s == "foobar")};
var myInterface = anon.ActLike<IFoobar>();
Or you could use an ExpandoObject
too:
dynamic expando = Build<ExpandoObject>.NewObject(Foobar: Return<bool>.Arguments<string>(s => s == "foobar"));
IMyInterface myInterface = Impromptu.ActLike(expando);
If you want to implement more than one interface, check my answer in this post.
Upvotes: 5
Reputation: 37113
Unfortunately anonymous classes in C# can´t implement interfaces as in Java. However you can create some kind of adapter-class without any additional dependencies on external projects. Just create a base-class that implements your interface using a Func
:
interface IFoo
{
bool DoSomething(string value);
}
class Bar : IFoo
{
private readonly Func<string, bool> m_DoSomething;
public Bar(Func<string, bool> DoSomething) { this.m_DoSomething = DoSomething; }
public bool DoSomething(string value)
{
return this.m_DoSomething(value);
}
}
Now you can call it like this:
var result = new Bar(x => true);
Or also using named arguments which is bit more obvious, in particular if your interface has more then one method:
var result = new Bar(DoSomething: x => true);
Only drawback is that you need an implementing class for every interface you have. Thus this approach is only usefull if you want to implement every interface more than once with different behaviour. So whenever I need different implementations for the same interface I use this approach.
Upvotes: 1
Reputation: 31799
It is possible to do a cleaner lambda syntax, however at the expense of static type checking inside Create()
.
I was able to use ImpromptuInterface to do this:
IFoobar foo = Implement.Interface(new {
Foobar = Function.Create(s => s == "foobar"),
});
By creating the following classes:
public static class Implement{
public static dynamic Interface(object source){
return Impromptu.ActLike(source);
}
}
public static class Function{
public static Func<dynamic> Create(Func<dynamic> del){
return del;
}
public static Func<dynamic,dynamic> Create(Func<dynamic,dynamic> del){
return del;
}
public static Func<dynamic,dynamic,dynamic> Create(Func<dynamic,dynamic, dynamic> del){
return del;
}
public static Func<dynamic,dynamic,dynamic,dynamic> Create(Func<dynamic,dynamic, dynamic,dynamic> del){
return del;
}
//...Add more if you want
}
Upvotes: 1
Reputation: 6876
Take a look at "impromptu-interface" (https://github.com/ekonbenefits/impromptu-interface).
It will allow you to do something like...
class Program
{
static void Main(string[] args)
{
Bar b = new Bar();
b.DoSomethingWithFoo(new
{
Foobar = Return<string>.Arguments<string>(r => "foo")
}.ActLike<IFoo>());
}
}
public interface IFoo
{
string Foobar(String s);
}
public class Bar
{
public void DoSomethingWithFoo(IFoo foo)
{
Console.WriteLine(foo.Foobar("Hello World"));
}
}
Upvotes: 6
Reputation: 79
You mentioned that you didn't need to do this often, don't care about performance, and usually want to do it during unit testing. Why not use a mocking framework?
For example, using the Moq library as an example:
public interface IFoobar {
Boolean Foobar(String s);
}
void Main() {
var foo = new Mock<IFoobar>();
foo.Setup(x => x.Foobar(It.IsAny<string>()))
.Returns((string s) => s == "foobar");
foo.Object.Foobar("notbar"); // false
foo.Object.Foobar("foobar"); // true
}
Upvotes: 7
Reputation: 44068
public class Foo
{
public Func<string,bool> TheDelegate {get;set;}
}
public class Bar
{
public bool Implementation(string s)
{
return s == "True";
}
}
public class Usage
{
var myBar = new Bar();
var myFoo = new Foo { TheDelegate = myBar.Implementation };
//Or
var myFoo = new Foo { TheDelegate = x => x == "True" };
//This removes the need for Bar completely
}
As you can see in the above example, java-like hacks are completely unneeded in C#, which is a much better language.
Upvotes: 1