What's wrong with my use of C# generics?

My code gives me error "cannot convert implicitly between int and T"

public class Vector3D<T>
{
    public T x; 
    public T y; 
    public T z;
    Vector3D()
    {
        x = 0;
        y = 0;
        z = 0;
    }
}
Jon Skeet
people
quotationmark

There's no implicit conversion available from the literal 0 to T. For example, T could be string, or TextField...

You may well want to limit your vector to struct types:

public class Vector3D<T> where T : struct

... but even so, you could have a Vector3D<DateTime>, and you can't convert 0 to DateTime. You can, however, use the default value for the type:

x = default(T);

But then, that's already the default value for each field, so you don't need the assignment at all.

At that point you can still come up with "odd" vectors (and you're going to find it hard to perform other operations on vectors, such as multiplying them by a scalar or adding them together) but at least it would compile.

Do you definitely need a generic type here? You may find that in the end it's more productive to have a few specific types (Vector3dInt32, Vector3dSingle, Vector3dDouble for example). I know it's not elegant, but given that there's no clean constraint for "T must be numeric" and no easy way of performing numeric operations on T, it may be the most practical solution.

You might also consider:

  • Do you definitely want a class, or would a struct be more appropriate? (If you must have a class, consider sealing it.)
  • I would avoid using public fields
  • I would strongly consider making the type immutable

people

See more on this question at Stackoverflow