【问题标题】:Casting Type array to Generic array?将类型数组转换为通用数组?
【发布时间】:2011-02-01 17:37:46
【问题描述】:

问题的简短版本 - 为什么我不能这样做?我仅限于 .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
}

【问题讨论】:

  • 你的课没有完成。我没有看到通用参数。不完整的代码比没有代码更糟糕。 ;-)
  • @Sky 代码已完成,但 George 未能正确转义 HTML (&lt;T&gt; ...)。
  • @康拉德和乔治。是的,我应该知道的。对不起。

标签: c# generics .net-3.5 arrays casting


【解决方案1】:

如果 T 定义为浮点数,通过 Vector&lt;T&gt; 定义为 Vector&lt;float&gt; 那么这将起作用(在受限 T 上),但如果您只想要本地转换:

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

当然,这无论如何都会将 T 限制为浮点数(编译器不能将任何内容转换为 T 并且知道这一点),如果是这种情况,看起来你应该在整个类中将 T 替换为浮点数,是吗?处理非浮点向量?

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

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

【讨论】:

    【解决方案2】:

    “通用”表示“适用于任何类型”。

    您的示例代码不是通用的,因为它仅在Tfloat 时才有效。


    虽然您不能将 Vector2D 转换为 Vector,但您当然可以将 Vector2D 转换为 Vector。向 Vector2D 添加Convert 方法或提供一组扩展方法,如下所示:

    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();
    

    【讨论】:

    • 简短版,是的。但整个想法是 Vector 可以是任何东西——我已经将它用于 int、float、double。 Unity 有一个 Vector2 和 Vector3 类型,我希望它们能够相互转换,这样我就可以处理我的更高级的通用版本,但为任何 Unity 函数提供它们的固定类型。即:Vector v = new Vector(3); Vector3 v3 = v;
    【解决方案3】:

    您不能在方法中暗示泛型参数的类型。

    而且,正如我之前所说,您发布的代码并不代表通用类型参数的有效用法。

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

    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);
        }
    }
    

    【讨论】:

      【解决方案4】:

      你说:

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

      以下工作(因为所有内容都可以转换为object,并且随后从object 转换为T 是允许的,但如果类型不兼容,或者在这种情况下如果取消装箱,则可能在运行时失败无法执行):

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

      也就是说,将类设为泛型绝对没有意义。

      【讨论】:

        猜你喜欢
        • 2013-05-01
        • 1970-01-01
        • 2015-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-13
        • 1970-01-01
        • 2021-09-09
        相关资源
        最近更新 更多