Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 396
lumberjack4 Avatar asked Apr 03 '13 21:04

lumberjack4


People also ask

Do extension methods have to be static?

An extension method must be a static method. An extension method must be inside a static class -- the class can have any name. The parameter in an extension method should always have the "this" keyword preceding the type on which the method needs to be called.

What is correct extension method?

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.

What is an advantage of using extension methods?

The main advantage of the extension method is to add new methods in the existing class without using inheritance. You can add new methods in the existing class without modifying the source code of the existing class. It can also work with sealed class.

What are extension methods explain with an example?

An extension method is actually a special kind of static method defined in a static class. To define an extension method, first of all, define a static class. For example, we have created an IntExtensions class under the ExtensionMethods namespace in the following example.


1 Answers

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.

like image 68
JaredPar Avatar answered Sep 22 '22 10:09

JaredPar