2

I am wondering if there is some inline short way of creating a class implementing a interface. Just like there are the anonymous methods but with implementing interfaces.

The problem is:

interface iSomeInterface
{
  void DoIt();
}

public void myMethod(iSomeInterface param)
{
 ...
}

And I would like to use it like this:

object.myMethod(new { override DoIt() { Console.WriteLine("yay"); } } : iSomeInterface);

Any ideas?

Sorry in case its a duplicate.

ninja hedgehog
  • 405
  • 4
  • 16
  • 1
    `Func` and `Action` and their variants may be useful for you to achive something similar... – S2S2 Sep 06 '13 at 10:42
  • 1
    You could use Moq - it would be a gross abuse of it's purpose, but it would allow you to create what are essentially anonymous classes. – RB. Sep 06 '13 at 10:47
  • @AlessandroD'Andria My need is inline declaring a class with interface implementation. Else I would have to write a new business object that implements the interface. – ninja hedgehog Sep 06 '13 at 10:49
  • Yes i understand this, what i didn't understood is WHY you want to create inline classes, what you gain instead of using other solutions (like Action of Func how suggested by @VS1 – Alessandro D'Andria Sep 06 '13 at 10:53
  • 9
    This isn't meant as mean or rude - really... But I would at least like to suggest that you stop trying to find 'ninja like tricky trick's in code to do things... Especially that 1 liner - almost made me scream... really.. As a person that does application support (works on old and new projects, sometimes without documentation), things where I am sure the developer thought what they were doing was REALLY COOL, end up usually being the point where a bug creeps in.. On top of that, it is hard to maintain, and hard to come back to after a while and know WTF you just did. – tostringtheory Sep 06 '13 at 10:55
  • @tostringtheory no offence but its a question, the world aint gonna end because of a one liner. The annonymous types are also ment to be used for small pojo's so you dont have to create a complete class because you will only use it once anyways in a method and then gc will collect it. Nobody would ever create a annonymous type and place 40 properties in it anyways. – ninja hedgehog Sep 06 '13 at 11:13
  • 2
    @ninjahedgehog To solve this in c#, it would not be a one liner. Dont be so lazy, create a new class. In the time it took you to write, maintain and comment on this stack, you could have written all the code you would need. – Gusdor Sep 06 '13 at 11:19
  • @tostringtheory the interface is IWeakEventListener and it has one method called ReceiveEvent. its microsoft interface so i have to use it. i havent designed it. i have to use it but i didnt want to create a public/internal class for it because i really need it at just one place only once and then gc may collect it. anyways its a question. lets not turn this into discussion – ninja hedgehog Sep 06 '13 at 11:24
  • 1
    possible duplicate of [Can a C# anonymous class implement an interface?](http://stackoverflow.com/questions/191013/can-a-c-sharp-anonymous-class-implement-an-interface) – nawfal Jun 28 '14 at 18:51
  • @tostringtheory almost 10 years later and it still hurts that this core feature is missing from C#. We now have dozens of fake classes litering the codebase (and often getting used in the wrong place, wrong way, or accidentally edited etc) just because you can't pass e.g. a Comparer to Dictionary any other way. The scoping is simple and clear: there is literally no legitimate use of those classes except in a single method call, but C# forces extra bug opportunities onto us :) – Adam Jun 15 '22 at 17:46

4 Answers4

5

Sorry, no inline implementation of classes in C#. There are only Anonymous Types, but they don't support adding interfaces (see for example Can a C# anonymous class implement an interface?) (nor they support adding methods or fields... They only support properties).

You can use the methods of System.Reflection.Emit to generate a class at runtime, but it's long and tedious.

Community
  • 1
  • 1
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • @ninjahedgehog There is non ninja-like tricky trick. Technically you could create a new class through Reflection, but it would be very much work. See for example http://stackoverflow.com/questions/15733900/dynamically-creating-a-proxy-class – xanatos Sep 06 '13 at 10:41
  • @ninjahedgehog If you want to accept a single-method interface (in your case one `void` method), instead accept an `Action`. – Patryk Ćwiek Sep 06 '13 at 10:42
  • Damn and I was looking for a ninja alike tricky trick. A static method that does the job and I just have to set what interface I wish to inject as parameter. – ninja hedgehog Sep 06 '13 at 10:42
3

You can create a class that wraps an Action and implements that interface:

public sealed class SomeAction : ISomeInterface
{
    Action action;
    public SomeAction (Action action) { this.action = action; }
    public void DoIt() { this.action(); }
}

This allows you to use it as follows:

object.myMethod(new SomeAction(() => Console.WriteLine("yay"));

This is of course only very practical if you are going to reuse SomeAction, but this is probably the most convenient solution.

g t
  • 7,287
  • 7
  • 50
  • 85
Steven
  • 166,672
  • 24
  • 332
  • 435
0

That is pretty common in java but there is no way you can do it in C#. You can pass a functions or procedures as parameters though:

public void myMethod(Action act)
{
    act();
}

myMethod( () => Console.WriteLine("yay") );

Several (generic) version of Action (procedure with parameters and no return value) and Func (functions with parameters and return value) exist.

BlackBear
  • 22,411
  • 10
  • 48
  • 86
0

Look for the "ImpromptuInterface" NuGet package. With the combination of this package and ExpandoObject, you can do something like this

//Create an expando object and create & assign values to all the fields that exists in your interface
dynamic sigObj = new ExpandoObject();
sigObj.EmployeeKey = 1234;

//Create the object using "ActLike" method of the Impromptu class
INewSignatureAcquired sig = Impromptu.ActLike<INewSignatureAcquired>(sigObj);
Tosh
  • 531
  • 7
  • 3