I have a special case. I need to rewrite a library and I do not have the original code. To make the discussion clearer lets call the library HandlerLibOld and HandlerLibNew.
I want to make HandlerLibNew that shall replace HandlerLibOld.
I have an application that uses this library, and it is big application with 1000s of calls to the library. I rather not have to change the application code.
Sample application code
public class MyMessage : MyBaseClass
{
public int ValueA {get;set;}
public int ValueB {get;set;}
}
public class MyOtherMessage : MyBaseClass
{
public int ValueC {get;set;}
public int ValueD {get;set;}
}
public class Sender
{
Handler handler = new Handler();
handler.Send<MyMessage>(m => { m.ValueA=10; m.ValueB=20; });
}
Notice the line handler.Send<MyMessage>(m => { m.ValueA=10; m.ValueB=20; });
. It uses a lambda expression to define an object of the MyMessage
and sets two properties of this object. Notice that I rather not have to change this code.
Maybe I have misunderstood what the lambda expression does, but the point is I need to tell the Handler.Send about the values ValueA and ValueB.
Now I want to write the implementation of the Send
method of the Handler
. The tricky part is that the lambda expression makes it an action, but I want to get the MyMessage object instance. How can I achieve that? Do I need to use reflection somehow?
My attempts
I have tried:
public class Handler
{
public void Send<T>(Action<T> actionmessage)
{
// actionmessage is an object of type Action<T>,
// I want to get the object of type T that was passed into the method.
}
}
I have also tried:
public class Handler
{
public void Send<T>(T message)
{
// This will not compile. I get:
// Cannot convert lambda expression
// to type 'object' because it is not a delegate type
}
}
I know it is possible somehow because this works with the HandlerLibOld. How can I achieve the same with HandlerLibNew? I don't have access to the code of HandlerLibOld.
CodePudding user response:
In order for that Action to work, you must have an instance of T to begin with:
public void Send<T>(Action<T> actionMessage)
where T: new()
{
var input = new T();
actionMessage(input);
//T has now valueA and valueB populated
//do more with input T
//send
}
Now if T were to have a constraint such as implementing a certain interface, you can do more stuff on the object itself. If you are using base classes you must be careful with object slicing.