Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing C# parameters which can "fit" an interface, but do not actually implement it

Note: I know this is an awful idea in practice; I'm just curious about what the CLR allow you to do, with the goal of creating some sort of 'modify a class after creating it' preprocessor.

Suppose I have the following class, which was defined in another assembly so I can't change it.

class Person {     public string Greet() => "Hello!"; } 

I now define an interface, and a method, like the following:

interface IGreetable {     string Greet(); }   // ...  void PrintGreeting(IGreetable g) => Console.WriteLine(g.Greet()); 

The class Person does not explicity implement IGreetable, but it could do without any modification to its methods.

With that, is there any way whatsoever, using Reflection, the DLR or anything else, in which an instance of Person could be passed successfully to PrintGreeting without modifying any of the code above?

like image 363
Aaron Christiansen Avatar asked Jan 29 '18 18:01

Aaron Christiansen


People also ask

What is passing in C?

Pass by Value, means that a copy of the data is made and stored by way of the name of the parameter. Any changes to the parameter have NO affect on data in the calling function.

What is parameter passing in C?

Parameter passing involves passing input parameters into a module (a function in C and a function and procedure in Pascal) and receiving output parameters back from the module. For example a quadratic equation module requires three parameters to be passed to it, these would be a, b and c.

Does C have pass-by-reference?

There is no pass-by-reference in C.

What is pass by address in C?

If you declare a formal parameter of a function as a pointer type, you are passing that parameter by its address. The pointer is copied, but not the data it points to. So, Pass By Address offers another method of allowing us to change the original argument of a function (like with Pass By Reference).


2 Answers

Try to use the library Impromptu-Interface

[The Impromptu-Interface] framework to allow you to wrap any object (static or dynamic) with a static interface even though it didn't inherit from it. It does this by emitting cached dynamic binding code inside a proxy.

This allows you to do something like this:

var person = new Person(); var greeter = person.ActLike<IGreetable>(); 
like image 165
Roy Sanchez Avatar answered Sep 28 '22 04:09

Roy Sanchez


You could use a dynamic wrapper object to wire this up yourself, but you lose type safety inside the wrapping class:

class GreetableWrapper : IGreetable {     private dynamic _wrapped;     public GreetableWrapper(dynamic wrapped)     {         _wrapped = wrapped;     }      public string Greet()     {         return _wrapped.Greet();     } }  static void PrintGreeting(IGreetable g) => Console.WriteLine(g.Greet()); static void Main(string[] args) {     PrintGreeting(new GreetableWrapper(new Person()));     Console.ReadLine(); } 
like image 42
John Koerner Avatar answered Sep 28 '22 03:09

John Koerner