当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - Using Explicit Cast in an Extension Method

问题描述:

I have a weird problem when I'm trying to cast an object via an extension method. I have a class where I wrap some functionality around an 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;

}

I don't like the look of all the parenthesis to extract the IPAddress out of the object:

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

I'd rather be able to do something like this:

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

In order to do this I wrote the following Extension Method:

public static T CastAs<T>(this object value) where T : class

{

return (T)value;

}

Unfortunately with this I'm getting an InvalidCastException:

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

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

I understand that in this particular case I could simply expose the IPAddress with a getter, but we also have more complex explicit casts that I would like to do this with.

EDIT

Thanks to Chris Sinclair's comment on using dynamic I have updated the extension method to look like:

public static T CastAs<T>(this object value)

{

return (T)((dynamic)value);

}

There is some overhead with using dynamic, but it is more than fast enough for my needs. It also seems to work with all the basic type casting I've tried.

网友答案:

In the first sample you are accessing the user defined conversion. This is only available when the cast operator knows the type of the input is PrefixLengthAddress. In the generic code the compiler only knows the type object and T. There is no way it can access the conversion defined on PrefixLengthAddress in this scenario.

In this scenario what you're doing is much closer to mapping vs. casting since it's actually creating a new value. In terms of LINQ you would want to use Select vs. Cast.

分享给朋友:
您可能感兴趣的文章:
随机阅读: