我使用 C# 泛型有什么问题

本文关键字:什么 问题 泛型 | 更新日期: 2023-09-27 18:31:54

我的代码给我错误"无法在 int 和 T 之间隐式转换"

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

我使用 C# 泛型有什么问题

您唯一错误的事情是为构造函数中的属性赋值。您无法执行此操作,因为T的类型在指定它并创建类的实例之前是未知的。编译器还不知道要使用哪种类型的方式:

public class Vector3D<T>
{        
    public T x; 
    public T y; 
    public T z;        
}

T的意思是:稍后在实例化类时,您可以在此处使用具体的东西。

例如,使用 int s:

var vector = new Vector3D<int>() 
{ 
    x = 0, 
    y = 0, 
    z = 0 
}; // I'm using the object initializer here.

它与:

var vector = new Vector3D<int>();
vector.x = 0;
vector.y = 0;
vector.z = 0;

但是,如果您已经知道需要 int s 的Vector,并且想要为其提供一些其他功能,则可以创建一个派生类型来设置T(在此处int),以便以后不必再次指定它:

public class Int32Vector3D : Vector3D<Int32>
{
    public Int32Vector3D()
    {
        x = 0;
        y = 0;
        z = 0;
    }
    // custom members for adding, subtracting, translating etc.
}
没有

从文字0T的隐式转换。例如,T可以是 string ,也可以是TextField...

您可能希望将向量限制为结构类型:

public class Vector3D<T> where T : struct

。但即便如此,你也可以有一个Vector3D<DateTime>,并且你不能将0转换为DateTime。但是,您可以使用该类型的默认值:

x = default(T);

但是,这已经是每个字段的默认值,因此您根本不需要分配。

在这一点上,你仍然可以想出"奇数"向量(你会发现很难对向量执行其他操作,例如将它们乘以标量或将它们相加),但至少它会编译。

这里肯定需要一个泛型类型吗?你可能会发现,最终拥有一些特定的类型(例如Vector3dInt32Vector3dSingleVector3dDouble)会更有效率。我知道这并不优雅,但鉴于"T必须是数字"没有明确的约束,也没有简单的方法来对T执行数字运算,这可能是最实用的解决方案。

您还可以考虑:

  • 你肯定想要一个类,还是结构更合适?(如果必须有一个类,请考虑将其密封。
  • 我会避免使用公共字段
  • 我强烈建议使类型不可变

正是它所说的。你那里有像"x=0"这样的代码 - 是一个整数常量。但不能保证 T 是 int,所以....这是无效的。没有隐式转换(并且您不会强制转换为 T)。

使用 int 类型的值初始化类型 T。不应将泛型类型用于 Vector。喜欢这个^

public class Vector3D
{
    public int x; 
    public int y; 
    public int z;
    Vector3D()
    {
        x = 0;
        y = 0;
        z = 0;
    }
}

编译器不知道 T 可以是 int,因此它会给你隐式错误。你可以类型转换它,但问题是你真的需要一个泛型类吗?或者只是一个整数并说浮动?