20

Just wondering if there is anyway to represent the following code in C# 3.5:

public struct Foo<T> {

    public Foo(T item) {
        this.Item = item;
    }

    public T Item { get; set; }

    public static explicit operator Foo<U> ( Foo<T> a )
        where U : T {

        return new Foo<U>((U)a.Item)
    }
}

Thanks

LaserJesus
  • 8,230
  • 7
  • 47
  • 65

3 Answers3

24

Conversion operators can't be generic. From the spec section 10.10, here's the format of a conversion-operator-declarator:

conversion-operator-declarator:
    implicit   operator   type   (   type   identifier   )
    explicit   operator   type   (   type   identifier   )

Compare this with, say, a method-header:

method-header: attributesopt method-modifiersopt partialopt return-type member-name type-parameter-listopt ( formal-parameter-listopt ) type-parameter-constraints-clausesopt

(Sorry about the formatting - not sure how to do it better.)

Note that the operator format doesn't include a type parameter list or type parameter constraints.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    And even if we did support user-defined generic conversions, this one would still be illegal. It is illegal to define a conversion that replaces a built-in conversion. This would do so if T and U were the same type; you would be replacing the identity conversion. – Eric Lippert Jun 22 '09 at 14:53
  • 3
    As casts are decided by the compiler, if T and U were the same type, then it wouldn't use the user defined cast, and be leagal. – Miguel Angelo Mar 16 '10 at 17:51
2

Your code boils down to the line: return new Foo<U>((U)a.Item)

Where you try to assign a baseclass to an inherited class, which is impossible.

Let's say T (base-class) is of type Stream and U is of type MemoryStream (inherited class), you cannot assign a Stream to a variable of type MemoryStream.

Gideon
  • 18,251
  • 5
  • 45
  • 64
  • Sure you can, If the reference masks the object as a Stream, but it is infact a MemoryStream, then you can certainly cast it to a Memory Stream. This is a legitimate method, the problem is that you can't actually specify generic constraints on an operator overload... – LaserJesus Jun 22 '09 at 05:54
  • ...If you take the code I have and express it as a method rather than an operator overload it will compile – LaserJesus Jun 22 '09 at 05:56
0

I think the short answer is "Not possible. Try using a method instead"

Also seems to be dupe of this question Solution for overloaded operator constraint in .NET generics

Community
  • 1
  • 1
Gishu
  • 134,492
  • 47
  • 225
  • 308