C#相当于VB.NET的DirectCast是什么?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (94)

C#是否具有与VB.NET的DirectCast相同的功能?

我知道它有()强制转换和'as'关键字,但是这些关键字符合CType和TryCast。

要清楚的是,这些关键字执行以下操作;

CType /()强制转换:如果它已经是正确的类型,则转换它,否则查找类型转换器并调用它。如果未找到类型转换器,则引发InvalidCastException。

TryCast /“as”关键字:如果它是正确的类型,则转换它,否则返回null。

DirectCast:如果它是正确的类型,则转换它,否则抛出InvalidCastException。

在我详细说明了上述内容之后,有些人仍然回答说()是等价的,所以我会进一步扩展为什么这不是事实。

DirectCast只允许在继承树上缩小或扩大转换。它不支持像()这样的不同分支之间的转换,即:

C# - 编译并运行:

//This code uses a type converter to go across an inheritance tree
double d = 10;
int i = (int)d;

VB.NET - 这不是编译器

'Direct cast can only go up or down a branch, never across to a different one.
Dim d As Double = 10
Dim i As Integer = DirectCast(d, Integer)

在VB.NET中等价于我的C#代码是CType:

'This compiles and runs
Dim d As Double = 10
Dim i As Integer = CType(d, Integer)
提问于
用户回答回答于

看起来很清楚,你想要的功能不在C#中。试试这个虽然...

static T DirectCast<T>(object o, Type type) where T : class
{
    if (!(type.IsInstanceOfType(o)))
    {
        throw new ArgumentException();
    }
    T value = o as T;
    if (value == null && o != null)
    {
        throw new InvalidCastException();
    }
    return value;
}

或者,即使它与VB不同,请将其称为:

static T DirectCast<T>(object o) where T : class
{
    T value = o as T;
    if (value == null && o != null)
    {
        throw new InvalidCastException();
    }
    return value;
}
用户回答回答于

好的,下面是一个C#方法,据称它基本上是DirectCast在VB.NET中做的。

static T DirectCast<T>(object o) where T : class
{
    T value = o as T;
    if (value == null && o != null)
    {
        throw new InvalidCastException();
    }
    return value;
}

以上是上述方法的问题:

  1. 它有一个where T : class约束,而DirectCast不是。
  2. 它把它的论点作为一个System.Object- 再次,不是真的DirectCast(至少不是我所知道的)。
  3. as不必要地使用(这就是为什么它首先有class约束); 打电话(T)o会抛出一个,InvalidCastException如果它不工作; 为什么要检查值是否匹配使用as,只抛出如果你已经走过(T)o路线开始时会抛出相同的异常?

该方法可以真正被重写以提供与以下相同的结果DirectCast

static T DirectCast<T>(object o) {
    return (T)o;
}

有趣的观察:实际上,所有这些方法都是在装箱,然后试图解开它。换句话说,DirectCast<int>(12.0)真的是一样的(int)(object)12.0(并且会抛出一个异常)。意识到这一点使得所提出的DirectCast<T>方法完全没有必要。

现在,DirectCast下面()是VB.NET和C#之间如何与“铸造”不同的示例:

VB:

Dim i As Integer = 12
Dim l As Long = DirectCast(i, Long) ' does not compile '

C#:

int i = 12;
long l = i; // DOES compile

好的,一个编译,另一个不编译。但看看这些代码。什么DirectCast时候你已经知道一个对象的类型?这不是一个现实的比较,因为在VB.NET中永远没有任何理由DirectCast像上面的代码那样调用。(如果你想在VB.NET中将一个已知类型System.Int32的值转换为一个类型的值System.Int64,你可以使用CLng,而不是)DirectCast。如果在那里有一个变量类型System.Object那么使用它是有意义的DirectCast,并且下面的代码确实是等价的:

VB:

Dim i As Integer = 12
Dim o As Object = i
Dim l As Long = DirectCast(o, Long) ' compiles, throws an exception '

C#:

int i = 12;
object o = i;
long l = (long)o; // compiles, throws an exception

所以我认为,DirectCast在VB.NET中,在任何情况下使用它(例如,在编译时不知道对象的类型)时,它与()C#中的直接类型转换相同

好吧,对我发布一些VB编码没有编译的耻辱。在重新考虑我在说什么之后,我撤回第二个答案,但保持第一个答案。

如果你指的的使用DirectCast,你需要知道类型的对象,并尝试将其转换为所需的类型,那么它一样的C#的()主演:

VB:

Dim o As Object = SomeObject()
Dim i As Integer = DirectCast(o, Integer)

C#:

object o = SomeObject();
int i = (int)o;

这是因为,如果o输入为a System.Object,那么()C#中的操作将尝试解除它。如果类型不完全匹配,这将失败; 例如,如果o是盒装的System.Double(int)o则会抛出异常,因为o 必须先将其拆箱,System.Double然后才能转换为System.Int32(如果您不相信我,请自行尝试!)。

注意:以下是不准确的,因为DirectCast没有进行扩展转换; 无论如何,我将它留给子孙后代。

另一方面,在处理扩展与缩小转换时(),正如已经指出的那样,在C#中使用操作比简单地执行操作更有效(即,您可以执行(int)someDouble)。在这种情况下,DirectCast相当于C#中的普通旧分配:

VB:

Dim i As Integer = 12
Dim l As Long = DirectCast(i, Long) ' does not compile, actually '

C#:

int i = 12;
long l = i;

扫码关注云+社区