1

原创(作品):

Dim fnt As Drawing.Font = New Drawing.Font( _
  rtf.SelectionFont.FontFamily, _
  rtf.SelectionFont.Size, _
  DirectCast(rtf.SelectionFont.Style _
  + If(rtf.SelectionFont.Underline, _
  -Drawing.FontStyle.Underline, _
  Drawing.FontStyle.Underline), _
  Drawing.FontStyle) _
)

翻译 () 不能将 FontStyle 转换为 int:

System.Drawing.Font fnt = new System.Drawing.Font(
  rtf_Renamed.SelectionFont.FontFamily, 
  rtf_Renamed.SelectionFont.Size,
  (System.Drawing.FontStyle)(
    rtf_Renamed.SelectionFont.Style 
    + rtf_Renamed.SelectionFont.Underline 
    ? -System.Drawing.FontStyle.Underline  //cannot cast to int
    : System.Drawing.FontStyle.Underline
  )
);

那么如何将这些 .NET 属性转换为它们的数值呢?

4

2 回答 2

4

我相信您的代码试图做的是如果原始代码没有下划线,则添加下划线,否则将其删除。

但是FontStyle应该是位掩码的,以便切换下划线部分。您不应该执行算术加法和减法,因为如果原始样式设置了任何其他属性,这将无法正常工作。

您必须进行 DirectCast 的事实是一个警钟,表明某些事情可能不正确。

您的 VB 代码应如下所示:

Dim fnt As Drawing.Font = New Drawing.Font(rtf.SelectionFont.FontFamily, 
                                           rtf.SelectionFont.Size, 
                                 rtf.SelectionFont.Style XOr FontStyle.Underline)

所以 C# 等价物应该是这样的:

Drawing.Font fnt = new Drawing.Font(rtf.SelectionFont.FontFamily, 
                                    rtf.SelectionFont.Size, 
                                 rtf.SelectionFont.Style ^ FontStyle.Underline);

有关此问题的一些背景信息,请参阅此问题:如何在实例化字体时设置多个 FontStyles?

于 2013-10-24T11:08:21.877 回答
2

rtf.SelectionFont.Style +...位是错误的。原VB代码应转换为:

Dim fnt As Drawing.Font = New Drawing.Font( _
  rtf.SelectionFont.FontFamily, _
  rtf.SelectionFont.Size, _
  DirectCast(rtf.SelectionFont.Style XOr If(rtf.SelectionFont.Underline, _
  -Drawing.FontStyle.Underline, _
  Drawing.FontStyle.Underline), _
  Drawing.FontStyle) _
)

直接转换为 C# 时出现此错误的原因是,在 VB 中,FontStyle接受直接转换为整数(注意下面),并带有所有规则(+/- 符号)。在 C# 中,您不能这样做,因此无法完全复制上面的代码(减号部分,实际上转换UnderlineStrikeout)。转换后的 C# 代码:

System.Drawing.Font fnt = new System.Drawing.Font(
  rtf_Renamed.SelectionFont.FontFamily, 
  rtf_Renamed.SelectionFont.Size,
  (System.Drawing.FontStyle)(rtf.SelectionFont.Style
    ^ rtf_Renamed.SelectionFont.Underline 
    ? System.Drawing.FontStyle.Strikeout
    : System.Drawing.FontStyle.Underline
  )
);

澄清

正如评论所指出的,原始的 VB 代码执行了一个实际上不应该执行的隐式转换(从FontType到)。Integer理想情况下,两个代码都应该依赖于适当的类型,因此依赖于SelectionFont.UnderlineFontStyle.Strikeout或执行相应的强制转换为Integer.

关于字体/枚举/CAST/VB的注意事项

FontStyleEnumSystem.Drawing.FontStyle 类型。通过执行相应的强制转换/转换,可以通过整数访问 Enum 的属性(除非Option Strict Off在 VB.NET 中有,否则不推荐)。因此,理论上,OP 代码的 VB 版本甚至不应该使用 Option Strict On 进行编译,但它可以!这个特定的配置(DirectCast 中的条件)似乎很好,即使 Option Strict On!没有实际影响的轶事事实(您应该始终使用并依赖 Option Strict On),但这很奇怪。

于 2013-10-24T11:26:33.163 回答