【问题标题】:VB vs C# — CType vs ChangeTypeVB 与 C# — CType 与 ChangeType
【发布时间】:2018-05-01 07:00:34
【问题描述】:

为什么这在 VB.Net 中有效:

Dim ClipboardStream As New StreamReader(
    CType(ClipboardData.GetData(DataFormats.CommaSeparatedValue), Stream))

但这会在 C# 中引发错误:

Stream是一个Type,在当前上下文中无效

ClipboardStream = new StreamReader(Convert.ChangeType(
    ClipboardData.GetData(DataFormats.CommaSeparatedValue), Stream));

说实话,我并不是 100% 了解转换类型,我只在代码 sn-ps 中使用过它们,现在我正在尝试将简单的 VB 代码 sn-p 转换为 C# 版本...

【问题讨论】:

  • 大约 5 分钟内有这么多很棒的答案 - 谢谢大家!!我会全部投票,但我必须接受@Sweeper 的回答,因为它帮助我理解最大的区别。
  • ClipboardData.GetData() 看起来像 Javascript :)
  • 我认为最初用 VB 编写代码的人是 Javascript 爱好者。

标签: c# .net vb.net


【解决方案1】:

ChangeType 接受Type 作为第二个参数,所以你应该写typeof(Stream)typeof(Stream) 计算为代表Stream 类型的Type 实例。仅使用 Stream 是行不通的,因为它不会评估为值。这不是一个表达式。

无论如何,你不应该在这里使用ChangeType,你应该cast,这是CTypeC# equivalent

 ClipboardStream = new StreamReader((Stream)ClipboardData.GetData(DataFormats.CommaSeparatedValue));

【讨论】:

  • 不,C# 的演员表等同于 VB 的DirectCastCType 可能执行可转换类型之间的转换。例如,var myString = (string)myInt 甚至无法编译,myInt as string 也无法编译,但 Ctype(myInt, String) 完全合法且有效。
【解决方案2】:

CType 是 VB.Net 中的编译器函数。它允许它的第二个参数是一个产生类型名称的表达式。你不能在 VB 或 C# 中自己编写这样的函数。

正如 Patrick 所说,使用 Convert 的 C# 将是:

ClipboardStream = new StreamReader(Convert.ChangeType(
ClipboardData.GetData(DataFormats.CommaSeparatedValue),typeof(Stream)));

但是这段代码更接近于如果 this 是用 VB 编写的:

ClipboardStream = New StreamReader(Convert.ChangeType( _
ClipboardData.GetData(DataFormats.CommaSeparatedValue),GetType(Stream)))
VB 中的

CType 更接近于 C# 中的 cast(例如 (Stream)... 而不是 CType(..., Stream)

【讨论】:

  • @PatrickHofman - 相当于typeof 的VB。努力改进措辞以表明第二个示例 VB。
  • 我现在没有要验证的 IDE,但 GetType() 应该只在比较或分配的右侧可用。
  • @Jimi - 查看示例(记得切换到 VB) - Convert.ChangeType
  • 嗯,是的,Convert.ChangeType() 接受它。但是,那么,ClipboardStream 会是什么样的类型呢?这是一个缩小转换(如果我没记错的话),即使 Option Strict 关闭也可能是无效的。我去看看。
  • 但是,我假设ClipboardData.GetData(),给定它的参数,等同于Clipboard.GetData()。这可能不是。
【解决方案3】:

因为在 C# 中传入类型与在 VB.NET 中不同。你应该使用typeof(Stream):

ClipboardStream = new StreamReader
                    ( Convert.ChangeType
                        ( ClipboardData.GetData(DataFormats.CommaSeparatedValue)
                        , typeof(Stream)
                        )
                    );

然而,在这种情况下,一个简单的演员会更好:

ClipboardStream = new StreamReader
                    ( (Stream)ClipboardData.GetData(DataFormats.CommaSeparatedValue)
                    );

【讨论】:

  • 谢谢。只是环顾四周,在 MSDN 上的一些代码示例上看到了 typeof,并打算尝试一下。我也不懂铸造,但它工作得很好,所以我会用它并尝试尽快阅读它:)
  • 这是不正确的。如果您要在 VB.NET 中使用Convert.ChangeType,您也无法传入类型名称;你必须传入一个类型实例。与 C# 的 typeof 运算符一样,它从类型名称中获取 Type 实例,VB.NET 具有 GetType 运算符:Convert.ChangeType(ClipboardData.GetData(DataFormats.CommaSeparatedValue), GetType(Stream))
【解决方案4】:

Convert.ChangeType 在其第二个参数中需要一个 Type 参数。要从变量中获取Type 实例,请调用GetType() 方法或使用typeof 运算符:

ClipboardStream = new StreamReader(Convert.ChangeType(
ClipboardData.GetData(DataFormats.CommaSeparatedValue), Stream.GetType()));


ClipboardStream = new StreamReader(Convert.ChangeType(
ClipboardData.GetData(DataFormats.CommaSeparatedValue), typeof(Stream)));

另一种方式(imo 首选方式)是使用强制转换运算符

ClipboardStream = new StreamReader((Stream)ClipboardData.GetData(DataFormats.CommaSeparatedValue));

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 2011-07-29
    • 2010-11-17
    • 1970-01-01
    • 2010-12-06
    • 2015-07-25
    • 2013-09-13
    • 2014-09-02
    • 1970-01-01
    相关资源
    最近更新 更多