【问题标题】:C#: How do I cast within a class to the template type? [duplicate]C#:如何在类中强制转换为模板类型? [复制]
【发布时间】:2021-12-17 16:32:15
【问题描述】:

首先,我是 C# 新手,来自 C/C++,我在语言实现中发现了很多烦恼。

我正在尝试做的事情:为“寄存器”创建一个通用字段。该字段将使用与寄存器大小相同的内部数据类型。所以一个 32 位寄存器将只有 32 位无符号内部数据。

作为错误检查传递给字段构造函数的值是否有效的一部分,我使用is 来确定最大位数。

public class Field<T>
{
  private t mask;
  public Field( T size, T position )
  {
    T maxBits = mask is UInt32 ? 32: mask is UInt64 ? 64 : 0;
  }
}

Program.cs:错误 CS0029:无法将类型“int”隐式转换为“T”

所以我改变了违规行:

T maxBits = mask is UInt32 ? (T)32: mask is UInt64 ? (T)64 : (T)0;

我得到了同样的错误,只是没有“隐式”这个词。

如何在 C# 的模板类中强制转换为类型 T?经过一个小时的互联网搜索,我意识到:不应该这么难。


更新: 感谢 cmets Caius Jard 和 Clemens。

我被两件事困扰。首先,我读了一篇博客,作者说“泛型和模板对我来说是一样的”。好吧,也许对作家来说;但不,他们不是!这助长了我对非模板的编译时评估而不是泛型的运行时评估的错误假设。

因此,我从 MS 文档中阅读了更多关于泛型的信息,而我想要对它们做的并不是它们的本意。这解释了我遇到的所有其他编译错误,让我知道没有办法修复它。 (关于简单数学的错误,如左移、比较等)。

感谢你的教育!

至于烦恼 - 我不认为我会停止烦恼,我会学会处理它。在使用 Bash 多年后尝试编写 PowerShell 脚本时,发生了这种情况。我觉得 MS 几乎 做对了,但并不完全正确。它只是进一步验证了我的观点,MS 的一切充其量都是平庸的。但是这个世界是在 MS 上运行的,所以……当我在这个 MS 应用程序上工作时,我会坐下来做一只脾气暴躁的 Linux 熊。哈哈

【问题讨论】:

  • 我在语言实现中发现了很多烦恼 - 一旦你停止假设因为两种语言都以字母 C 开头,它们应该消失你习惯的东西将在另一个中起作用。 C# 没有模板;泛型是不同的东西
  • 你的意思可能是int maxBits
  • T 是一种仅在运行时才知道的泛型类型。将 int 转换为未知类型不起作用。如上所述,将 maxBits 设为 int 类型应该可以解决强制转换问题。不过,我认为您遇到了问题。你到底想达到什么目标?

标签: c# templates casting


【解决方案1】:

这不起作用,因为T 可以是许多不同的类型。例如,您可以声明

var field = new Field<HttpClient>(new HttpClient(), new HttpClient()); 

这将使构造函数中的赋值等效于

HttpClient maxBits = mask is UInt32 
    ? (HttpClient)32 
    : mask is UInt64 ? (HttpClient)64 : (HttpClient)0;

显然这没有意义。您不能将值 32 分配给 HttpClient 类型的变量。

编译器无法知道 T 的运行时类型是什么,这意味着它可能对您尝试的强制转换无效。编译器的工作是在你运行代码之前发现这样的潜在问题,这样你在运行代码时就不会遇到运行时错误。这与int x = "Hello"; 无法编译的原因相同。

generic constraints 告诉编译器更多关于T 的类型。但是没有通用约束表明T 只会是UInt32UInt64。所以你需要一个不同的解决方案来解决这个问题。


一种选择可能是定义一个enum,它只包含您想要允许的值,例如

public enum FieldBits // I'm guessing - I don't know if this
{                     // makes sense for what you're trying to do.
    Zero = 0          // It's just to give you an idea.
    ThirtyTwo = 32,
    SixtyFour = 64
}

如果你将这个枚举传递给你的构造函数,那么类就知道要使用这些值中的哪一个,并且如果不使用这些值之一就不可能调用构造函数。然后您可以使用该枚举值来确定maxBits 的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 2017-08-12
    • 2018-03-18
    • 2017-10-05
    相关资源
    最近更新 更多