I'm using a third party library class that has the following (abbreviated) method:
public void DoSomethingAsync(Action<ResultInfo> callback)
Rather than have a reference to this third party library in my application code project, I've created a wrapper class that abstracts the third par开发者_JS百科ty dependencies. So, what I'm trying to do is have a wrapper method that looks like the following:
public void MyDoSomethingAsync(Action<MyResultInfo> callback)
{
this.wrappedClass.DoSomethingAsync(callback);
}
The problem is that I need to convert the callback
parameter from Action<MyResultInfo>
to Action<ResultInfo>
. Is this possible with a custom implicit cast operator or is there an alternative approach that someone can recommend?
No, you wouldn't be able to do so directly, even if MyResultInfo
derived from ResultInfo
; delegate contravariance wouldn't apply here as the Action<MyResultInfo>
wouldn't be able to handle any instance derived from ResultInfo
(so that disqualifies an Action<MyResultInfo>
from being used in place of an Action<ResultInfo>
)
However, that doesn't mean you can't use an adapter, like so:
public void MyDoSomethingAsync(Action<MyResultInfo> callback)
{
// Create the action which will transform ResultInfo
// into MyResultInfo and then pass to the wrapped
// class.
// Create the action first.
Action<ResultInfo> a = ri => {
// Translate ri into MyResultInfo.
MyResultInfo mri = (translate here);
// Call the callback with the translated result.
callback(mri);
};
// Pass the action to the wrapped class.
this.wrappedClass.DoSomethingAsync(a);
}
The problem is that what you want to make may result in inconsistency. I assume that MyResultInfo
is derived from ResultInfo
because otherwise it doesn't make any sense.
Now back to inconsistency. Imagine that you have delegate Action<ResultInfo> callback
. Calling code could call it like this: callback(new MyResultInfo());
and call your Action<MyResultInfo>
and it will work fine. But imagine it is called like this: callback(new ResultInfo());
, Action<ResultInfo>
allows it, but it will produce exception because ResultInfo
can't be cast to MyResultInfo
.
精彩评论