csa*_*uve 49 c# vb.net casting ctype directcast
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;
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
VB.NET与我的C#代码的等价物是CType:
'This compiles and runs
Dim d As Double = 10
Dim i As Integer = CType(d, Integer)
Run Code Online (Sandbox Code Playgroud)
Gre*_*mil 13
很明显,你想要的功能不在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;
}
Run Code Online (Sandbox Code Playgroud)
或者,即使它与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;
}
Run Code Online (Sandbox Code Playgroud)
第二次更新:
好的,这是一个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;
}
Run Code Online (Sandbox Code Playgroud)
以下是上述方法的问题:
where T : class约束,DirectCast但没有约束.System.Object- 再次,不是真的DirectCast(至少不是我所知道的).as不必要地使用(这就是它首先有class约束的原因); InvalidCastException如果它不起作用,则调用(T)o将抛出; 为什么要检查值是否匹配使用as,只是为了抛出相同的异常,如果你已经(T)o开始使用该路由就会被抛出?真的可以重写该方法以提供与以下相同的结果DirectCast:
static T DirectCast<T>(object o) {
return (T)o;
}
Run Code Online (Sandbox Code Playgroud)
有趣的观察:真的所有这个方法都是装箱值,然后尝试拆箱.换句话说,它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 '
Run Code Online (Sandbox Code Playgroud)
C#:
int i = 12;
long l = i; // DOES compile
Run Code Online (Sandbox Code Playgroud)
好的,所以一个编译,另一个不编译.但看看那段代码.什么是点DirectCast的时候,你已经知道了对象的类型?这不是一个现实的比较,因为在VB.NET中,没有任何理由DirectCast像上面的代码那样调用.(如果你想将一个已知类型System.Int32的值转换为System.Int64VB.NET中的类型值,你可以使用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 '
Run Code Online (Sandbox Code Playgroud)
C#:
int i = 12;
object o = i;
long l = (long)o; // compiles, throws an exception
Run Code Online (Sandbox Code Playgroud)
所以我DirectCast在VB.NET中保持这种情况,在任何实际使用它的情况下(即,在编译时不知道对象的类型),与()C#中的直接式强制转换相同.
编辑:嗯,我发布一些没有编译的VB代码感到羞耻.在重新考虑我说的话后,我撤回了第二个答案,但保留了第一个答案.
如果你指的的使用DirectCast,你需要知道类型的对象,并尝试将其转换为所需的类型,那么它是一样的C#的()主演:
VB:
Dim o As Object = SomeObject()
Dim i As Integer = DirectCast(o, Integer)
Run Code Online (Sandbox Code Playgroud)
C#:
object o = SomeObject();
int i = (int)o;
Run Code Online (Sandbox Code Playgroud)
这是因为,如果o输入为a System.Object,那么()C#中的操作将尝试将其解包.如果类型不完全匹配,则会失败; 例如,如果o是盒装System.Double,那么(int)o将抛出一个异常,因为o 必须先将其拆箱,System.Double然后才能将其转换为a 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 '
Run Code Online (Sandbox Code Playgroud)
C#:
int i = 12;
long l = i;
Run Code Online (Sandbox Code Playgroud)