6

拡張メソッドを介してオブジェクトをキャストしようとすると、奇妙な問題が発生します。にいくつかの機能をラップするクラスがありIPAddressます。

// Dumbed down version of class
public sealed class PrefixLengthIPAddress
{
    public static explicit operator IPAddress(PrefixLengthIPAddress address)
    {
        return (address != null) ? address._address : null;
    }

    public PrefixLengthIPAddress(IPAddress address)
    {
        _address = address;
        _length = address.GetLength();
    }

    private readonly ushort _length;
    private readonly IPAddress _address;
}

IPAddressオブジェクトから抽出するためのすべての括弧の外観が好きではありません。

var family = ((IPAddress)prefixLengthAddress).AddressFamily;

私はむしろ次のようなことができると思います:

var family = prefixLengthAddress.CastAs<IPAddress>().AddressFamily;

これを行うために、次の拡張メソッドを作成しました。

public static T CastAs<T>(this object value) where T : class
{
    return (T)value;
}

残念ながら、これで私は得ていInvalidCastExceptionます:

var family = ((IPAddress)prefixLengthAddress).AddressFamily;         // Works
var family = prefixLengthAddress.CastAs<IPAddress>().AddressFamily;  // InvalidCastException

この特定のケースでは、ゲッターを使用して単純に公開できることを理解していますが、IPAddressこれを行いたい、より複雑な明示的なキャストもあります。

編集

使用に関する Chris Sinclair のコメントのおかげでdynamic、拡張メソッドを次のように更新しました。

public static T CastAs<T>(this object value)
{
    return (T)((dynamic)value);
}

を使用すると多少のオーバーヘッドがありますがdynamic、私のニーズには十分な速度です。また、私が試したすべての基本的な型キャストでも動作するようです。

4

1 に答える 1