我已经-never-用as
或者is
在C#或支持关键字的任何语言。
你有什么用它来做什么?
我不意味我如何使用我的意思是你怎么样真的需要它?
我也逃离了相当大的C ++项目(我很自豪)这样做没有类型转换。
因此,考虑到我几乎从来没有强制转换,为什么我需要的关键字as
或者is
?
我已经-never-用as
或者is
在C#或支持关键字的任何语言。
你有什么用它来做什么?
我不意味我如何使用我的意思是你怎么样真的需要它?
我也逃离了相当大的C ++项目(我很自豪)这样做没有类型转换。
因此,考虑到我几乎从来没有强制转换,为什么我需要的关键字as
或者is
?
我不得不写代码来枚举所有放置在ASP.NET Web窗体控件和具体的控件执行特定操作,如添加背景颜色到所有文本框,等等。
最大的好处as
和is
对我来说,我可以放心地检查变量是否是使用给定类型的is
没有异常情况发生。 有一次,我敢肯定,这是一个给定类型的,我可以安全,轻松地将其转换为使用所需要的类型as
。
我基本上没有(简单!)是
foreach(Control c in form.Controls)
{
if(c is Textbox)
HandleTextbox(c as Textbox);
if(c is Listbox)
HandleListbox(c as Listbox);
}
等等。 如果没有as
和is
这将是一个很大混乱,恕我直言。
基本上,你可能需要或可以好好利用的as
和is
,如果你与多态性处理很多-如果你有事情可以在我的示例页面上任意数量的类型,如控制列表。 如果你没有或不使用多态很多,你不可能遇到的那些运营商的需求。
渣
我用“作为”作为事件处理一个方便快捷获取发送对象回来时,我不知道在设计时的发送者。
protected void SomeButtonInAGridView_Click(object sender, EventArgs e)
{
Button clickedButton = sender as Button;
}
这里有一个很多出现:
class Foo {
public override bool Equals(object obj)
{
// The more specific function needs to do null checking anyway.
return Equals(obj as Foo);
}
public bool Equals(Foo obj)
{
// do some comparison here.
}
}
有趣的问题。 其实,我用他们所有的时间。 is
很方便找出一个对象是否是某种类型的,我用的就是偶尔在仿制药或循环通过不同类型的对象。 这也是非常宝贵的与反思。
另外, as
发现有更多的用途。 它往往是更安全的使用,然后正常投:当它失败时,它返回的不是一个异常空。 我也觉得它更清晰的语法和更容易使用它,检查返回值零,然后添加一个异常块。
基本上,我的意思是说,我喜欢这样的:
protected void GeneralEventHandler(object sender, EventArgs e)
{
Button btn = sender as Button;
if(btn != null) // click came from a button!
// do something
else
// other cases
}
还有这个:
protected void GeneralEventHandler(object sender, EventArgs e)
{
if(sender is Button) // click came from a button!
// do something
else
// other cases
}
与此相反:
protected void GeneralEventHandler(object sender, EventArgs e)
{
try
{
Button btn = (Button) sender;
// if we get this far, it's a button
}
catch(InvalidCastException ice)
{
// click did not come from a button! Handle other cases
}
}
当然,这只是一个例子,但是当我能避免的try / catch,我会的。 这也让更多的空间真正的例外打通。
我用它来清洁从获取数据DataReader
,可能是DBNull
。
int? personHeight = dr["Height"] as int?;
要么
int personHeight = dr["Height"] as int? ?? 0;
下面是从埃里克利珀描述如何“为”在C#中使用一个帖子:
http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx
我所有的时间使用。 当我给拉了回来,从会话缓存序列化对象,我用,以确定序列化对象是存在的,正确的类型。 我能避免程序抛出一个错误,使用操作人员和检查空。 如果是空的,我知道缺少的东西,我可以重新创建对象,并把它推回缓存,下一次我需要它。
你可以通过完成强制转换运算符相同的结果,但增加了一个异常的开销,尤其是当你知道序列化的对象是不会在那里的部分时间。
C#报价方式投用就是和运营商。 的是操作者检查对象是否与给定类型兼容,评价的结果是一个布尔值:真或假。 is运算符绝不会抛出异常。 下面的代码演示:
System.Object o = new System.Object();
System.Boolean b1 = (o is System.Object); // b1 is true.
System.Boolean b2 = (o is Employee); // b2 is false.
如果对象引用为null,因为没有可用的对象,以检查它的类型就是运营商始终返回false。
is运算符,通常使用如下:
if (o is Employee) {
Employee e = (Employee) o;
// Use e within the ‘if’ statement.
}
在这段代码中,CLR实际上是检查对象的类型两次:是运营商首先检查如果o是与员工类型兼容。 如果是,那么if语句里面,CLR再次验证Ø执行转换时,指的是员工。
C#提供了一种方法来简化这个代码,并通过提供作为运营商提高其性能:
Employee e = o as Employee;
if (e != null) {
// Use e within the ‘if’ statement.
}
在该代码中,CLR检查如果o是与雇员类型兼容,并且如果它是,作为返回一个非空指针到相同的对象。 如果o是不得与劳动者类型兼容,那么作为运营商返回null。
如果你开发一个项目,提供了一个插件接口则as
和is
很快就会成为你最好的朋友。
这里还有一个用例进入卡里加里博士的小屋;-)
您可以链as
运营商,如:
x = obj as Label as Control;
你为什么会做这样的事? 如果你想为空,如果它不是一个标签,但你要正确对待他们所有的控制。 只是投放文本框和标签直接控制会产生成功的两个,现在这将是空不想要的类型的控制。 这是你会不会经常需要一个快捷的方法,但偶尔得心应手。
对于相同的另一种用途是,当你需要ToString()
的对象上,但只有当它是正确的类型,否则,你需要有一个默认的字符串。 这是我遇到的很多时候,ESP的情况。 与波苏斯。 因为ToString()
是虚拟的,这工作:
// assume SomeClass has overridden ToString()
// return "none" if item is not of type SomeClass or if it is null to begin with
string itemText = (item as SomeClass as Object ?? "none").ToString();
C-风格的转换(如(Foo)bar
)将抛出InvalidCastException
,如果转换失败。 as
,在另一方面,将产生null
(见本 )。 is
操作者只是用于测试给定实例的运行时类型是否与所提供的类型(见兼容此 )。
is
被广泛使用in.NET System.ComponentModel命名空间。 更具体地讲, 类型转换器 API在很大程度上依赖于is
运营商以确定如何从一种类型转变为另一种。
我在WinForms应用程序那里是编辑发票的GUI使用这两个关键字广泛,在各行ListView
可能包含不同类型的项目(即,它可能是一个行项目或描述,或......)。 所有我放在项目ListView
是源自ListViewItem
,所以再后来就当我去实现诸如编辑所选项目的事情,我必须检查哪些项目类型选择(使用is
),以显示相应的编辑界面。
自定义类型转换器是第一位在脑海中。
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
return GetEnumValue(myVal, (string)value);
}
if (value is Enum)
{
return GetEnumDescription((Enum)value);
}
return base.ConvertFrom(context, culture, value);
}
第二来自哪里我有一个对象(用于跟踪的变化)的阴影是从基类继承的情况下
class BaseClass
{
BaseClass _shadow;
}
protected override void UpdateShadow()
{
ThisClass shadow = _shadow as ThisClass;
//...
}
如果你真的永远不必做铸造话,我很可能你就不会为这些运营商多大用处。 根据我的经验,但是,.NET编程呼吁了很多与设置的参数类型为“对象”代表打交道时,特别铸造的。 我认为,引入泛型有助于削减需要铸造,但它肯定是我很经常使用的东西。 我可能是“做错了”,但是,这只是我的经验。
所以,如果你打算做铸造反正我很喜欢的“是”,以提高代码的可读性运营商。 我宁愿看
if(foo is SomeType) {...}
然后
if(foo.GetType() == typeof(SomeType)) {...}
marc_s的回答是一个小瑕疵,我看到这个代码,所有的时间,所以我想强调这些运营商之间的差异的重要性。 is
是布尔测试,以确定对象是否是分配给一个特定类型。 as
检查是否对象被分配给一个特定类型的,并且如果是,则返回该对象作为该类型,如果没有,它返回null。 marc_s的答案是真的这样做
foreach(Control c in form.Controls)
{
if(c is Textbox)
HandleTextbox(c is Textbox ? (Textbox)c : null);
if(c is Listbox)
HandleListbox(c is Listbox ? (Listbox)c : null);
}
它是多余的使用is
有as
。 无论你使用的时候as
刚与上面的表达式替换它,就相当于。 使用is
直接管型()
或as
唯一本身。 一种更好的方式来写的例子是。
foreach(Control c in form.Controls)
{
if(c is Textbox)
HandleTextbox((Textbox)c);
//c is always guaranteed to be a Textbox here because of is
if(c is Listbox)
HandleListbox((Listbox)c);
//c is always guaranteed to be a Listbox here because of is
}
或者,如果你真的喜欢as
foreach(Control c in form.Controls)
{
var textBox = c as Textbox;
if(textBox != null)
{
HandleTextbox(textBox);
continue;
}
var listBox = c as ListBox
if(listBox != null)
HandleListbox(listBox);
}
我碰到的所有时间一个真实世界的例子从一个存储区,只有返回类型的对象获取对象。 缓存是一个很好的例子。
Person p;
if (Cache[key] is Person)
p = (Person)Cache[key];
else
p = new Person();
我使用的as
在真正的代码要少得多,因为它真的只适用于引用类型。 考虑下面的代码
int x = o as int;
if (x != null)
???
as
失败,因为一个int不能为空。 is
工作正常,虽然
int x;
if (o is int)
x = (int)o;
我相信也有这些运营商之间的一些速度差,但对于实际的应用中的差别可以忽略不计。