我想知道在下面的代码中使用关键字"as"是否是一种安全的方式(即不会爆炸)在C#中进行转换:
public void abc(ref Object dataSource)
{
DataTable table = dataSource as DataTable;
}
Run Code Online (Sandbox Code Playgroud)
有更安全的铸造方式吗?
Jon*_*eet 42
它不会爆炸......但这并不一定意味着它是安全的.
通常当我使用强制转换进行引用转换时,这是因为我真的认为执行时类型是我指定的类型.如果不是,则表示我的代码中存在错误 - 我宁愿将其表现为异常.
如果您的系统中存在不良数据,那么继续好像一切都很好是危险的路径,而不是安全路径.这就是as采取你的方式,而演员会抛出一个InvalidCastException,在你有机会用糟糕的数据造成混乱之前中止你所做的一切.
as如果它对于不属于给定类型的对象有效 - 如果它不表示错误则是好的.你几乎总能看到以下模式:
Foo x = y as Foo;
if (x != null)
{
...
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅MSDNas.
另请注意,您可能不希望ref在方法中使用.有关详细信息,请参阅有关参数传递的文章.大部分时间,如果我看到人们使用ref了很多,那是因为他们不明白它的真正含义:)
Jus*_*gan 13
这取决于你所说的"安全".问问自己哪个更安全:带断路器的设备,还是没有断路器的设备?没有保险丝的人更有可能完成洗衣服,但也更容易烧毁你的房子.
您可能知道,在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
Run Code Online (Sandbox Code Playgroud)
不同之处在于,如果运行时不知道如何转换myObject为MyType,则第一行将抛出异常,而第二行将仅设置foo为null.如果居住的对象myObject不是a MyType,或者没有任何明确的强制转换MyType,就会发生这种情况myObject.
哪一个更安全?好吧,如果"安全"意味着"如果演员表无效则不会抛出异常",那么as表格更安全.如果施法失败,(MyType)myObject会立即爆炸,但myObject as MyType只有当你试图做一些foo你不能做的事情时才会爆炸null(比如打电话foo.ToString()).
另一方面,有时抛出异常是最安全的事情.如果您的代码中有错误,您可能想立即知道.如果myObject总是期望是a MyType,那么失败的演员意味着某处有一个错误.如果你继续进行铸造工作,那么你的程序会突然处理垃圾数据!它可能会进一步爆炸,使调试变得困难,或者 - 更糟糕 - 它可能永远不会爆炸,只是静静地做你没想到的事情.这可能会造成各种各样的破坏.
因此,这两种形式都不具有内在的安全性或正确性,它们只适用于不同的事物.您可以使用以下myObject as MyType表格:
myObject的myObject,但只有它是类型的MyTypemyObject可能是其他东西MyType,并不意味着有一个错误一个例子是当你有一组不同的WebForm控件时,你想要清除它们中的所有TextBox:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您的TextBox就会被清除掉,其他一切都会被遗忘.
DataTable table = dataSource as DataTable;
Run Code Online (Sandbox Code Playgroud)
如果演员阵容不成功,as则返回使用null,因此不会爆炸.-这意味着你将不得不处理的情况下,table是null在你的代码的其余部分,虽然.