2010-03-28 41 views
3

问题的简短版本 - 为什么我不能这样做?我仅限于.NET 3.5。将数组类型转换为通用数组?

T[] genericArray; 

// Obviously T should be float! 
genericArray = new T[3]{ 1.0f, 2.0f, 0.0f }; 

// Can't do this either, why the hell not 
genericArray = new float[3]{ 1.0f, 2.0f, 0.0f }; 

加长版 -

我与Unity引擎在这里工作,虽然这并不重要。什么是 - 我试图在其固定的Vector2(2个浮点数)和Vector3(3个浮点数)与我的通用Vector类别之间进行转换。我不能直接将类型转换为泛型数组。

using UnityEngine; 

public struct Vector<T> 
{ 
    private readonly T[] _axes; 

    #region Constructors 
    public Vector(int axisCount) 
    { 
     this._axes = new T[axisCount]; 
    } 

    public Vector(T x, T y) 
    { 
     this._axes = new T[2] { x, y }; 
    } 

    public Vector(T x, T y, T z) 
    { 
     this._axes = new T[3]{x, y, z}; 
    } 

    public Vector(Vector2 vector2) 
    { 
     // This doesn't work 
     this._axes = new T[2] { vector2.x, vector2.y }; 
    } 

    public Vector(Vector3 vector3) 
    { 
     // Nor does this 
     this._axes = new T[3] { vector3.x, vector3.y, vector3.z }; 
    } 
    #endregion 

    #region Properties 
    public T this[int i] 
    { 
     get { return _axes[i]; } 
     set { _axes[i] = value; } 
    } 

    public T X 
    { 
     get { return _axes[0];} 
     set { _axes[0] = value; } 
    } 

    public T Y 
    { 
     get { return _axes[1]; } 
     set { _axes[1] = value; } 
    } 

    public T Z 
    { 
     get 
     { 
      return this._axes.Length < 2 ? default(T) : _axes[2]; 
     } 
     set 
     { 
      if (this._axes.Length < 2) 
       return; 

      _axes[2] = value; 
     } 
    } 
    #endregion 

    #region Type Converters 
    public static explicit operator Vector<T>(Vector2 vector2) 
    { 
     Vector<T> vector = new Vector<T>(vector2); 

     return vector; 
    } 

    public static explicit operator Vector<T>(Vector3 vector3) 
    { 
     Vector<T> vector = new Vector<T>(vector3); 

     return vector; 
    } 
    #endregion 
} 
+3

你的课程不完整。我看不到通用参数。不完整的代码比没有代码差。 ;-) – 2010-03-28 12:18:49

+0

@Sky代码已完成,但乔治未能正确转义HTML(''...)。 – 2010-03-28 12:28:34

+0

@Konrad&George。是的,我应该明白这一点。抱歉。 – 2010-03-28 13:13:53

回答

2

“通用” 的意思是 “任何类型的作品”。

您的示例代码不是通用的,因为它只适用于当且仅当Tfloat


虽然你不能一个的Vector2D转换为矢量<牛逼& GT,你可以,当然,转换的Vector2D到Vector <浮动>。添加Convert方法的Vector2D或提供一套扩展的方法是这样的:

public static class VectorExtensions 
{ 
    public static Vector<float> ToGenericVector(this Vector2D vector) 
    { 
     return new Vector<float>(vector.X, vector.Y); 
    } 

    public static Vector2D ToVector2D(this Vector<float> vector) 
    { 
     return new Vector2D(vector.X, vector.Y); 
    } 
} 

用法:

Vector<float> v = new Vector<float>(3, 5); 

Vector2D v2 = v.ToVector2D(); 
+0

简短的版本,是的。但是,整个想法是,矢量可以是任何东西 - 我用它为int,float,double。 Unity有一个Vector2和Vector3类型,我希望能够将它转换为和来自我可以处理我远远优越的通用版本,但喂养任何Unity功能他们的固定类型。即: Vector v = new Vector (3); Vector3 v3 = v; – 2010-03-28 12:31:36

+0

非常好 - 谢谢! – 2010-03-28 12:43:40

1

如果T通过Vector<T>Vector<float>定义为浮动,那么这将工作(在限制性T),但如果你只想要一个的局部转换:

var genericArray = new float[3]{ 1.0f, 2.0f, 0.0f }; 

当然,这限制了T无论如何都是一个浮点数(编译器不能将任何东西转换为T并知道这一点),看起来你应该在整个类中用float替换T,如果是这样的话,你在处理非浮点向量吗?

在这种情况下,你需要这样的东西:

var genericArray = new T[3]{ X, Y, Z }; 
1

你不能从一个方法中暗示泛型参数的类型。

而且,如前所述,您的发布代码并不代表泛型类型参数的有效用法。

泛型参数将在类或方法签名中定义。

public class Class1<T> 
{ 
    public T[] Method(params T[] args) 
    { 
     return args; 
    } 
} 

public class Demo 
{ 
    public Demo() 
    { 
     var c1 = new Class1<float>(); 
     float[] result = c1.Method(1.1f, 2.2f); 
    } 
} 
+0

看到我上面的评论。 – 2010-03-28 12:34:26

0

你说:

// This doesn't work 
this._axes = new T[2] { vector2.x, vector2.y }; 

下工作(因为一切都可以转化为object,并从objectT随后的转换是允许的,但可能会在运行时,如果失败类型不兼容,或者在这种情况下,如果拆箱不能执行):

this._axes = new T[2] { (T)(object)vector2.x, (T)(object)vector2.y }; 

也就是说,使这个类通用是绝对没有意义的。