С новыми динамическими возможностями в.NET 4.0, кажется, что должно быть возможно динамично реализовать интерфейс, например, данный:
public interface IFoo
{
string Bar(int baz);
}
public class Foo : IFoo
{
public string Bar(int baz) { return baz.ToString(); }
}
public class Proxy : IDynamicMetaObjectProvider
{
private readonly object target;
public Proxy(object target) { this.target = target; }
// something clever goes here
}
Затем я надеюсь, что существует некоторый способ позволить записать:
dynamic proxy = new Proxy(new Foo());
IFoo fooProxy = (IFoo)proxy; // because the target object implements it
string bar = fooProxy.Bar(123); // delegates through to the target implementation
Но пока еще я не уверен, что заменить // something clever goes here
с.
Так, мои вопросы:
Действительно ли это на самом деле возможно сделать с динамическим временем выполнения? Кажется, что динамично реализующие вещи как методы и свойства довольно легки, но я не нашел документации о динамичной реализации интерфейсов и преобразований в них.
Принятие этого возможно, насколько трудный это, вероятно, будет? (Можно предположить, что я - достойный программист с большим количеством опыта вещей как отражение, но в новинку для динамической платформы.)
Есть ли какие-либо ресурсы, которые помогли бы указать на меня в правильном направлении для реализации чего-то вроде этого? Или даже образцы, где такого рода вещь была уже сделана, что я могу использовать в качестве начальной точки?
Насколько я знаю, невозможно без ручного вмешательства написать или сгенерировать код, который перенаправляет члены интерфейса в обернутый экземпляр. Если вы хотите видеть поддержку такого рода вещей со стороны Microsoft, вы можете проголосовать на https://connect.microsoft.com/VisualStudio/feedback/details/526307/add-automatic-generation-of-interface-implementation-via-implementing-member. .
Думаю, я написал библиотеку, которая делает то, что вы хотите ... Она называется DynamicWrapper (на CodePlex), и она автоматически оборачивает класс, чтобы реализовать интерфейс. Это то, что вы хотите?
Явное приведение, as
и is
не работают из-за сравнения типов с вашим базовым классом прокси, но неявное приведение может вызвать DynamicObject.TryConvert, так что вы можете вернуть внутренний объект вместо динамического.
- TryConvert MSDN Documentation
Хотя приведенный ниже код работает, это не делегирование интерфейса как таковое, а только раскрытие внутреннего состояния. Похоже, вам нужно что-то вроде шаблона перехвата, например, DynamicWrapper Брайана.
dynamic wrapper = new Proxy(new Foo());
IFoo foo = wrapper;
foo.Bar();
class Proxy : DynamicObject
{
...
public override bool TryConvert(ConvertBinder binder, out object result)
{
Type bindingType = binder.Type;
if (bindingType.IsInstanceOfType(target))
{
result = target;
return true;
}
result = null;
return false;
}
}