正在使用“;作为“;在C#中是一种安全的铸造方式
本文关键字:安全 一种 方式 作为 | 更新日期: 2023-09-27 17:59:20
我想知道在以下代码中使用关键字"as"是否是在C#中进行铸造的安全方法(即不会爆炸):
public void abc(ref Object dataSource)
{
DataTable table = dataSource as DataTable;
}
有更安全的铸造方法吗?
它不会爆炸。。。但这并不一定意味着它是安全的。
通常,当我使用强制转换进行引用转换时,这是因为我非常非常认为执行时间类型就是我指定的类型。如果不是,那就表明我的代码中有一个错误——我宁愿它表现为一个例外。
如果你的系统中有坏数据,那么继续一切正常是危险的路径,而不是安全的 如果 有关 还需要注意的是,可能不希望在方法中使用as
对于对象不是给定类型的有效,则它是好的——如果它不指示错误。你几乎总是看到的模式:Foo x = y as Foo;
if (x != null)
{
...
}
as
功能的更多详细信息,请参阅MSDN。ref
。有关更多详细信息,请参阅我关于参数传递的文章。大多数时候,如果我看到人们经常使用ref
,那是因为他们不明白它的真正含义:)
这取决于你所说的"安全"是什么意思问问自己哪个更安全:带断路器的电器还是没有断路器的?没有保险丝的更有可能洗完你的衣服,但也更有可能烧毁你的房子。
正如您可能知道的,在C#中有两种主要的显式强制转换方法:
foo = (MyType)myObject; //Cast myObject to MyType or throw an error
foo = myObject as MyType; //Cast myObject to MyType or set foo to null
不同的是,如果运行时不知道如何将myObject
强制转换为MyType
,则第一行将抛出异常,而第二行仅将foo
设置为as
0。如果生活在myObject
中的对象不是MyType
,或者无论myObject
是什么,都没有显式转换到MyType
,就会发生这种情况。
那么,哪一个更安全呢?好吧,如果"safe"表示"如果强制转换无效,则不会引发异常",那么as
形式更安全。如果铸造失败,(MyType)myObject
会立即爆炸,但只有当你试图对foo
做一些你不能对null
做的事情(例如调用InvalidCastException
0)时,myObject as MyType
才会爆炸。
另一方面,有时抛出异常是最安全的做法。如果您的代码中有错误,您可能想立即知道。如果myObject
总是被期望为MyType
,那么转换失败意味着某个地方存在错误。如果您继续执行强制转换,那么突然之间,您的程序正在处理垃圾数据!它可能会进一步爆炸,使调试变得困难,或者——更糟的是——它可能根本不会爆炸,只是悄悄地做你意想不到的事情。这可能会造成各种破坏。
因此,这两种形式都不是本质上安全或正确的,它们只是对不同的事情有用。如果:,您将使用myObject as MyType
表格
- 你不知道
myObject
是什么类型 - 您想使用
myObject
执行某些操作,但前提是它的类型为MyType
myObject
可能不是MyType
,这并不意味着存在错误
一个例子是,当你有一个不同的WebForm控件的集合,并且你想清除其中的所有文本框:
foreach (var control in controls)
{
var textbox = control as TextBox;
if (textbox != null)
{
//Now we know it's a TextBox, so we know it has a Text property
textbox.Text = string.Empty;
}
}
这样,你的文本框就被清空了,其他的东西就不用管了。
DataTable table = dataSource as DataTable;
如果施放不成功,使用as
会返回null
,所以不会爆炸。-这意味着您必须在代码的其余部分中处理table
是null
的情况。
as
不会爆炸,但如果强制转换失败,变量将设置为null。你需要检查一下那个箱子。
DataTable table = dataSource as DataTable;
if (table == null)
{
// handle case here.
}
如果这就是你所说的"安全",它不会抛出异常。但是,如果强制转换失败,table
将为null。
DataTable table = dataSource as DataTable;
如果强制转换失败,则不引发异常。将改为null。
DataTable table = (DataTable)dataSource;
如果强制转换失败,将引发异常。
在这方面是安全的,但是如果强制转换可能失败,那么添加一个null检查来处理它。
这是一种安全的强制转换方式,因为它不会导致异常。然而,如果你不小心,它可能会导致隐藏的错误。
使用as
时,如果强制转换失败,则生成的变量为null
。如果您不检查这一点,那么稍后当您尝试访问变量时,您将得到一个NullReferenceException
,并且它失败的原因将不太清楚(例如,它是null
,因为强制转换失败还是后来做了其他事情导致它为空)
如果强制转换无效,"as"运算符不会引发异常。它只是返回null。()方法将引发异常。所以要回答你的问题,这是最安全的方法。
以下是你需要采取的基本方法:
if( x is MyType )
{
MyType y = (MyType) x;
}
或
MyType y = x as MyType;
if( y != null )
{
// Do stuff
}
取决于您要做什么:
DataTable table = dataSource as DataTable;
if (table != null) ...
意思是"dataSource
可能是DataTable
,我要检查它不是null
。"
DataTable table = (DataTable) dataSource;
意思是"dataSource
应该肯定是DataTable
,如果不是,那就大错特错了"。
使用as
和普通强制转换的区别在于,如果无法执行强制转换(因为对象类型不对),as
运算符将返回null
。正常的强制转换将引发异常。
所以他们都是"安全的"——当演员阵容无法成功时,他们会有不同的行为。
如果dataSource可以被转换为DataTable,那么它就可以安全地完成任务。但如果你担心它不能成功转换,你可以先检查dataSource。GetType()等于您试图将其强制转换为的类型。
如果您使用as,则不会出现运行时InvalidCastException,但表可能为null,因此需要进行检查。