发表评论
"除了string以外的其他类型都有Parse方法,用于将基本类型转换为字符串类型"
这一句好像反了,应该是将字符串类型转换为基本类型。感谢您的分享!
@随风流月
除了string以外的其他类型都有Parse方法?应该是“其他的Primitive Type”吧
“as操作符在执行效率上更胜一筹”,我觉得比较准确的说法是利用as模式比is模式具有更好的性能,毕竟is和as两个操作符本身不具有可比性。因为采用as模式只进行一个类型的验证,而is模式则会进行两次。
常用于访问通用对象缓存情况下,如
Person p = new Person()
session["keyName"] = p;
Person p = session["keyName"] as Person;
cache.Add("keyName", p)
Person p = cache.Get("keyName") as Person;
@布尔
对,其实,对象转型的情况下,都可以考虑以as模式类判断,否则应该进行异常处理。
@Anytao
异常处理是最不应该推荐的方法,这种方法的性能将会非常地差。
@Artech
异常处理是有性能损失,但是对可以预见的异常发生,我的理解是以性能换稳定,as模式中我们就可以捕捉NullReferenceException异常来处理,我觉得更加妥当。
effective c# 里面也有一个item是讲这个问题的,按照里面的意思是 尽量使用as ,:)
你好,我想请教一个问题。
在.net环境写的程序,怎样在没有装.net的机子上运行?就是客户机不装.net环境。更简单的说,就是如何把.net程序转换成win32程序。
非常感谢!!!!
若方便的话,可以给我发email:17look@163.com 或 qq: 624611400 .
谢谢大家了!!!!!!!!!
@Anytao
当然Exception Handler就像是给Application上了个保险。我的意思是尽量预测出现类不能兼容的情况,尽可能不要让Exception Handler起作用。
有这样一个原则:不到万不得已,不要把抛出Exception作为一种运行的条件来设计你的程序。
@duanxingchuan
我们一般通过.NET编写的托管的程序,托管程序的执行必须有个托管的执行环境,也就是必须加载CLR,所以托管程序在没有.NET,也就是没有安装.NET Framework(CLR + FCL)的环境中是不能执行的。
@Artech
所言甚是,异常处理最重要的是预见可能出现的异常,这样对性能对安全都是应该的。
大概意思讲了,但是不够详细。
可以参考Effective C#,我觉得那里讲得最详细。
回:Effective C#这本书怎么样呢?
答:这本书很烂
@Sean(陈阳)
@宋欢.net
@阿齐
这本书我没有研读过,大家都提到,可以找时间看看, Effective C++倒是看过,确实是经典。至于Effective C#,还是有时间再来讨教。
@周奔驰
不是标题党,是内容党,以内容和观点说话,标题只是个摆设.
is 和 as 的用处在某种程度上讲是不挨边的
is 是判断可否将一种类型当作另一种类型使
as 是将一种类型转为另一种类型,转换失败则返回null
就是从你的文章里我也看不出is 和 as有啥恩怨情仇~~~~
as 为类型转换,但是他要求转换以后的类型为引用类型(不晓得是否正确)
int a = 1;
object b=a;
int c = b as int //这里就会提示错误2 as 运算符必须与引用类型一起使用(“int”是值类型)
如果这样的话是不是说 as 只能用与
class A
{
.....
}
A a = new a();
object b=a;
A c= b as A;
@doll-net
某种程度上,is和as是可以拿出来比较,作为类型转换中的一种常用的手段,注意什么,推荐什么,这是本文的主题。
在此强调的是类型安全。
用as来转换类型是方便了也保证了安全性,而且不用Try catch……
is 和 as 应该说各有各的用处,只看具体情况了
@念时
某种意义上,是这样,这也是.NET本身的优点。
--引用--------------------------------------------------
镜涛: 更赞同 is用来判断,as用于转换!
--------------------------------------------------------
同意
有个疑问
A a = new a();
object b=a;
A c= b as A;
这样的转化跟
A a = new a();
object b=a;
A c= (A)b;
对比,具体有什么区别呢?
@嘟嘟嘟嘟
as实现了引用类型的强制转换,不会引发异常,b as A可以等效于:
b is A ? (A)b : null
而显示类型转换不具有该特性,总结其主要区别:
1 as只能操作引用类型;(type)变量名可以应用于值类型和引用类型;
2 as不会引发不兼容类型转换异常,有性能优势;显示类型转换,可能引发异常,不推荐。
@嘟嘟嘟嘟
:-), 不敢不敢,我很喜欢讨论,谢谢参与。
呵呵,文章很好
只是导航没做好吧?找了很久没发现有到下一回的链接呃~
所以本文的推荐是:
A a = new A();
object b = a; //这是隐式,与is 和as 无关
A c= b as A; //这是LZ推荐的引用类型转换机制,对吗?
如果不成功c为null(当然这里是成功的了:))
if(c==null)
{
您打算 throw exception在这里吗?
}
@第4只苹果
所言正确,对于c==null是否抛出异常,视具体的情况而定,而抛出异常是通常的选择。
--引用----------------------------------------------
Anytao: @嘟嘟嘟嘟
as实现了引用类型的强制转换,不会引发异常,b as A可以等效于:
b is A ? (A)b : null
而显示类型转换不具有该特性,总结其主要区别:
1 as只能操作引用类型;(type)变量名可以应用于值类型和引用类型;
2 as不会引发不兼容类型转换异常,有性能优势;显示类型转换,可能引发异常,不推荐。
--------------------------------------------------------
b as A可以等效于:
b is A ? (A)b : null 这样的话使用 as 不是一样需要两次兼容检查吗?性能为何会好呢?
@玄武湖到西湖
我提到的
------------------------------
b as A可以等效于:
b is A ? (A)b : null
-----------------------------
是对as语义的解释,而非实际的执行过程,实现上你可以从IL的分析或者二者的差别:
object a = new object();
A b = a as A;
if (a is A)
{
A c = (A)a;
}
可以根据其IL进行进一步的分析,即可知执行兼容性检查的本质:-)
@yiyisawa.Liu
呵呵,欢迎常来看看:-)
程序员都有挑剔和骄傲的情节。
“在.NET中,一切类型都必须集成自System.Object类型”原文中打错字啦,应该是继承。
说实话我不知道为什么总是推荐用哪个,然后说什么好不好,效率什么的。。。就是一个小小的is和as至于影响效率么?
还有真的有把很不相关的两个类用is或者as搞到一起的么。。。
如果按照这样的思路去学语言会不会有点舍本逐末。
ps:我只看了这一篇,并且我自认也是个新手。还请高手回答我的疑虑。谢谢。
from千冰念
@YITIAN Studio
首先谢谢你的指正。
关于is和as实质上是两张模式,在实际的系统中对于类型的判定常常是必须的,因为很多时候你并不清楚接受的参数是否是一个兼容的类型,就像你说的一样两个不相关类型的变量是经常会搞到一起的。
非安全的类型参数或者变量会引起系统灾难,这是类型检查存在的意义,也就是is和as存在的意义,一种实现的手段。
@dream one minute
呵呵,欢迎欢迎:-)
请问这句话在表述上是不是有点错误哦,反正我在第一次看的时候没有明白过来。
如果结果判断为空,则强制执行类型转换将抛出NullReferenceException异常。
不知道是不是我还没有理解清楚。正在拜读的你文章中。。。
--引用--------------------------------------------------
如果结果判断为空,则强制执行类型转换将抛出NullReferenceException异常。
-------------------------------------------------------
呵呵,写的快了点儿,表达欠妥。如果结果判断为空,强制执行类型转换,相当于对null执行操作,则将抛出NullReferenceException异常。
LZ,看了你的文章,解释得很清楚,说得很好!
虽然我是第一次接触C#,不过一看就懂,之前我用的是JAVA,
现在感觉C#跟JAVA几乎没什么大的区别,就同is的用法一样,
JAVA里面用的是 instance of,也是用来判断一个对象是否属于一个类的一个事例的.
呵呵,LZ,有机会得好好向你请教请教啊!
@@chenfeng.tang
随时恭候。Java和c#在语言特性上有很多类似,但是也存在不少差别,所以了解差别,兼顾共性,会很好。
看了一下感觉is和as就是用来判断类型是否相同的,我写程序好像都没有用到过,:( 能不能告诉我is和as一般在哪些应用中会用到啊?谢谢。
请问楼主“任何类型转换为其派生类型时,必须进行显示转换,转换的规则是:(类型名)对象名; ”一个对象能强制转换成它的派生类吗?那这段代码为什么编译不过呢
internal class A
{
//...
}
public sealed class Program
{
public static void Main()
{
object o1 = new object();
A a1 = (A)o1;//把object类型转换成A类型,编译不通过
}
}
什么是类型兼呢,呵呵,谢谢
@赵俊
文中已有详细的示例。一般来说,is常做类型兼容检查,而as用来做类型转换:-)
@Done
一个对象能强制转换成它的派生类吗?
答案是:能。否则一个违反Liskov替换原则的面向对象语言,何以面见万千程序开发者的颜面:-)
另外,你提供的代码显然是没有问题的,不知为何编译通不过:-)
LZ ,你好看了你的文章我有一个疑问:
class a {}
A a = new A();
//object o = new object();
object o =a;
A a1 = o as A;
if (a1==null)
{
}
为什么o=new object()就返回null ,而o=a就不为null
object o=a是不是已经隐士的进行了转换了,new 的为什么不行?
ps: 本人新手
@Done
一个对象当然能转换成任何类,引用类型之间的转换,要用as
你用的是啥??是强制类型转换,去看看强制类型转换的使用再说吧
@hhe
object o = new object();返回的是null吗???
那o.toString()有怎么解释呢?要知道null.toString()是要砍头的
@nobodyknow
砍头,o(>﹏<)o千万别,,我说的是a1 :-)
@hhe
@hazel
@nobodyknow
你们的讨论实在太精彩了:-)
基于你的问题,我想还是回到as的规则来了解就一目了然了:
检查对象类型的兼容性,并返回结果,如果不兼容就返回null;
不会抛出异常;
如果结果判断为空,则强制执行类型转换将抛出NullReferenceException异常。
其实A a1 = o as A;时a1是否为null完全取决于类型兼容性检查的结果,你看到的结果也就是类型检查的结果罢了。
--引用--------------------------------------------------
hhe: LZ ,你好看了你的文章我有一个疑问:
class a {}
A a = new A();
//object o = new object();
object o =a;
A a1 = o as A;
if (a1==null)
{
}
为什么o=new object()就返回null ,而o=a就不为null
object o=a是不是已经隐士的进行了转换了,new 的为什么不行?
-------------------------
去看看多态条件
ps: 本人新手
--------------------------------------------------------
O(∩_∩)O~:
as 运算符必须用于引用类型或可为 null 的类型;
呵呵,补充一点。
Liskov替换原则,不是指子类应该能够完全替换父类么?一个父类对象转换为其子类对象,编译通过,但意义又何在呢?会有什么样的应用场景呢?本人初学,望指教 :)
is 和 as 作用明显不同, 没有可比性.
建议as前先is判断.
@子逸
如果你够清楚,那么可比性之说本来就无从谈起,如果你不够清楚,那么比较比较也有助于认识清楚。
关于as之前先is判断,我觉得倒大可不必,因为as本身就有兼容性检查的过程,大可不必二次轮询。
@Done
@Fonlue
MyBase derivedObject = new MyDerived();
MyBase baseObject = new MyBase();
MyDerived derivedCopy1 = (MyDerived) derivedObject; // OK
MyDerived derivedCopy2 = (MyDerived) baseObject; // Throws exception
上面的代码都是合法的C#代码(从句法的角度来看,是合法的),是把基类转换为派生类。但是,最后的一个语句在执行时会抛出一个异常。在进行数据类型转换时,会检查被引用的对象。因为基类引用实际上可以引用一个派生类实例,所以这个对象可能是要转换的派生类的一个实例。如果是这样,转换就会成功,派生的引用被设置为引用这个对象。但如果该对象不是派生类(或者派生于这个类的其他类)的一个实例,转换就会失败,抛出一个异常。
就单纯的is和as操作符而言,我认为并没有任何性能上差异,你说的as模式和is模式应该是强制类型转换模式,当is为true时还要在if语句中再进行一次这样的[(类型名)对象名]形式的转换, 这时CLR会再次验证类型的兼容性,而as操作符返回的要么是对象的引用,要么是null,这时我们只要判断是否为null就行了,避免了再一次进行类型兼容性检查。
完全没必要,as就是为了避免我们在类型转换时的多次类型兼容性检查,你倒好,现在is,as全用,如果是这样,用一个is就OK了,不要用as
因为as前面的对象要转化为as后面的类型对象,这个对象的类型必须是as后面类型本身或它的子类,而object类型是所有类型的必须直接或间接继承的的根类,所以它只有as它自己的类型才能as成功,哈哈。
一个晕字了得,object o1=new object();这里的o1你可以把它看成一个指针,他可以引用所有直接或间接继承自它的类,这里o1指向的是一个object类型的实例,所以你想把这个实例转化为其它类型的变量(指针)是不行的,你可以想象一下,A类型是一个继承自object类的类型,里面如果有实现的话,假如多一个方法public void Func();这时你将一个object实例转换成A类型的实例,假如让你通过转换,这时你调用a1.Func()会成功吗?当然不会,因为object类型中根本没这个方法,当然你object o1=new object();里的o1也不会有,这肯定会出错的。所以我们说类型转换,其实转换不是类型,而是类型实例,就是你的类型变量引用的那个真正的类型实例,如果你用object o1=new A();这时o1引用的就是A类型的一个实例,这时再将o1转换时A a1=(A)o1;就不会出错,因为o1指向的实例正是A类型实例。
我觉得,is 和 as 本身是没有什么可比性。但是在类型转换时可以用它们来保证类型安全。这应该是这篇文章想要表达的吧。
is 是用来判断能不能做转换,结果为False就不执行转换代码,这样可以保证类型安全。
as 是转换后,转换成功就返回对象,转换失败结果为null,所以通过判断结果是否为null,可以保证类型安全。
我一直怀疑微软当初设计is的时候并不是用来做类型转换的用的,只是做类型判断,那做类型判断除了接下来做类型转换我想不出还有什么用?所以如果is除了上面说的作用之外再没有其它的用,可以直接舍弃了,一个as就够了,我觉的。
不过事实不是如此,哈哈。
C#为我们做引用类型的转换提供了一个操作符as,as只能用于引用类型,还有一个用于类型判断的is,is操作符可以即用于值类型也可以用于引用类型。
我开始感觉对:“任何类型转换为其派生类型时,必须进行显示转换,转换的规则是:(类型名)对象名”是理解了!大概就是下面的基类object可以显示转换为派生类int
object obj = "123";
int i = (int)obj;
Console.Write("{0}", i);
但是当我使用继承时,基类(父类)转换为其派生类(子类)时,编译能通过,但运行是会出现未处理InvalidCastException异常,代码如下:
class Animal
{
private float _weight;
public float Weight
{
get { return _weight; }
set { _weight = value; }
}
private int _feet;
public int Feet
{
get { return _feet; }
set { _feet = value; }
}
public void SelfType()
{
Console.Write("My Type is Animal! I have {0} feet and my weight is {1}! ",Feet,Weight);
}
}
class Cat : Animal
{
public void SelfType()
{
Console.Write("My Type is Cat! I have {0} feet and my weight is {1}!",Feet,Weight);
}
}
class Program
{
static void Main(string[] args)
{
Animal a = new Animal();
a.Feet = 2;
a.Weight = 3.4F;
if (a is Animal)
{
Cat c = (Cat)a;
c.SelfType();
}
else
{
Console.Write("My type is not {0}!", a.GetType());
}
}
}
编译没错,但当执行到Cat c = (Cat)a;
时会抛出:未处理InvalidCastException异常,异常信息为无法将类型Animal的对象强制转换为类型Cat。
这让我对此有产出了质疑,理论上来说应该可以显示转换的,那为什么又会异常呢?是不是我理解上出了偏差,还请指教?
非常感谢楼主的文章,受益匪浅,不过本人有点疑问,望请楼主不吝指教!
文章中举例:is典型用法为:
1 object o = new object();
2
3 class A
4
5 {
6
7 }
8
9 if (o is A) //执行第一次类型兼容检查
10
11 {
12
13 A a = (A) o; //执行第二次类型兼容检查
14
15 }
例子中if(o is A) 好像一直否会返回false吧?因为o的类型为object!
那如果假设object是类型B的基类的话,是不是应该就是:
if(o is object)
{
B b = (B)o;
}
else
{
console.write("o is null");
}
这样就避免了NullReferenceException异常,但是对B b = (B)o;是不是还可能存在InvalidCastException异常?
这里假设:B为int类型,o被复制为字符串,o="asdf"!
不知道这里InvalidCastException异常是不是只能用try...catch避免呢?
本贴子以“现状”提供且没有任何担保,同时也没有授予任何权利。
This posting is provided "AS IS" with no warranties, and confers no rights.
这些内容是啥意思?
看了您的文章跟下面的评论,有个效率的问题想问下,例子如下:
string a=string.Empty;
a=obj(object类型) as string;
a=(string)obj;
a=convert.ToString(obj);
a=obj.ToString();
哪个更好些啊,就效率跟安全性而言,希望指教
@勇赴
呵呵 is判断完成后不一定要进行类型转换,比如用接口实现多态的时候,用N多个类型继承一个基类,但每个子类各有差别,有的实现了某个接口,有的没有实现,当你遍历一个包含了N多个子类的基类数组时,遍历每一个元素是否实现某一个接口(用is判断),如果实现了,就调用该方法。书上看的 共同探讨