ProxyFoo is currently v0.x.x, which means that the API is subject to change.

Duck Proxies

Duck proxies are proxies that delegate subject members to a real subject (inner object). This allows the real subject to be used as if it implements the subject interface even though it may not do so directly.

Example

public class Sample
{
    public void DoSomething();
}

public interface IDoSomething
{
    void DoSomething();
}

A duck proxy can be used to "cast" an instance of the Sample class to an object that implements IDoSomething.

Usage

A duck proxy is created with the following static method call:

using ProxyFoo;

object obj = null;
var result = Duck.Cast<IDoSomething>(obj);

or when using object extensions:

using ProxyFoo.ExtensionsApi;

object obj = new Sample();
var result = obj.Duck<IDoSomething>();

There will be a small amount of overhead in the first call, but significant effort was made to maximum the performance of multiple casts.

Calling a method repeatedly or multiple methods on the resulting proxy object has almost no overhead. A cast of this form performs better than using dynamic after about 3 method calls.

For repeated casts to the same subject interface a higher performance option is available in the following form:

using ProxyFoo;

var fastCaster = Duck.GetFastCaster<IDoSomething>();
var result = fastCaster(obj);

This is useful for a factory scenario or when casting multiple objects in a loop. This reduces overhead such that a cast of this form performs better than using dynamic after about 2 method calls.

Binding

Methods from the subject interface are bound to members of the real subject by name. The overload that is the closest match will be selected. The following conversions are allowed when matching argument and return value types:

Conversion Description
Identity A match to the exact same type.
Implicit Numeric

See Implicit Numeric Conversions Table

long a = (int)4;

From Section 6.1.2*

Implicit Nullable

Allows a conversion from a value type to its nullable type including an implicit numeric conversion if needed.

int? a = 4;

From Section 6.1.3*

Implicit Reference

Includes conversions between dynamic and object, base and derived classes, and other standard C# reference conversions.

object obj = new Sample();

From Section 6.1.6*

User Defined

Allows the conversion based on a user-defined type conversion operator. See C# implicit.

User-defined type conversions from base class types are not currently utilized.

From Section 6.1.11*

Duck Cast

When an interface is the type being converted to and reference type (class) is being converted from, a duck cast conversion is bound. If the real subject type cannot successfully be duck cast then the resulting value is a null.

*of the C# Language Specification 5.0