ความแตกต่างระหว่าง is และ as คำสำคัญ


121

โปรดบอกความแตกต่างระหว่างisและasคำหลักใน C # คืออะไร


7
เป็นตามหรือเป็นอย่างไร blogs.msdn.com/b/ericlippert/archive/2010/09/16/…
LukeH

3
หากคุณสนใจเรื่องนี้คุณอาจต้องการทราบความแตกต่างระหว่างโอเปอเรเตอร์ "as" และ "cast": blogs.msdn.com/b/ericlippert/archive/2009/10/08/…
Eric Lippert

7
คุณต้องการทำเครื่องหมายคำตอบที่ยอมรับหรือไม่ จะช่วยให้ผู้อื่นมองหาคำตอบที่คล้ายกัน
KMån

คำตอบ:


151

คือ

ตัวisดำเนินการจะตรวจสอบว่าวัตถุสามารถส่งไปยังประเภทใดประเภทหนึ่งได้หรือไม่

ตัวอย่าง:

if (someObject is StringBuilder) ...

เช่น

ตัวasดำเนินการพยายามที่จะส่งวัตถุไปยังชนิดที่ระบุและส่งคืนค่าว่างหากล้มเหลว

ตัวอย่าง:

StringBuilder b = someObject as StringBuilder;
if (b != null) ...

ที่เกี่ยวข้อง:

การคัดเลือกนักแสดง

ประกอบการโยนความพยายามที่จะโยนวัตถุประเภทที่เฉพาะเจาะจงและพ่น exeption ถ้ามันล้มเหลว

ตัวอย่าง:

StringBuilder b = (StringBuilder)someObject.

4
ไม่ถูกต้อง isไม่ได้ตรวจสอบว่าออบเจ็กต์สามารถส่งเป็นประเภทเฉพาะได้หรือไม่ จำนวนเต็มใช้ค่าปรับแบบยาว แต่10 is longเป็นเท็จ
Martin Smith

9
@MartinSmith: คุณกำลังผสมการแปลงประเภทกับการคัดเลือกนักแสดง จำนวนเต็มสามารถแปลงเป็น long ได้ แต่ไม่สามารถแปลงเป็น long ได้เนื่องจากไม่ใช่ long
Guffa

2
คุณกำลังบอกฉันว่าจำนวนเต็มไม่สามารถร่ายยาวได้? ที่(long)some_integerจะล้มเหลว? ฉันค่อนข้างแน่ใจว่าเราทั้งคู่รู้ว่านั่นไม่เป็นความจริงโดยไม่ต้องเรียกใช้ดังนั้นโปรดอธิบายว่าคุณหมายถึงอะไร
Martin Smith

12
@MartinSmith: คุณยังคงสับสนในการคัดเลือกนักแสดงกับการแปลง คุณไม่ได้แคสต์จำนวนเต็มเป็นค่า long คุณกำลังแปลงจำนวนเต็มเป็น long แม้ว่าจะใช้ไวยากรณ์เดียวกัน แต่การอ้างอิงจะถูกแคสต์และมีการแปลงค่า
Guffa

2
หมายเหตุเกี่ยวกับis : " โปรดทราบว่าโอเปอเรเตอร์is จะพิจารณาเฉพาะการแปลงอ้างอิงการแปลงชกมวยและการแปลงแบบ unboxing เท่านั้นการแปลงอื่น ๆ เช่น Conversion ที่ผู้ใช้กำหนดจะไม่ได้รับการพิจารณา " (msdn.microsoft.com/en-us/library/scekt9xw ขอบ) เกี่ยวกับas : " โปรดทราบว่าโอเปอเรเตอร์asดำเนินการเฉพาะการแปลงอ้างอิงการแปลงที่เป็นโมฆะและการแปลงชกมวยตัวดำเนินการ as ไม่สามารถทำการแปลงอื่น ๆ เช่น Conversion ที่ผู้ใช้กำหนดซึ่งควรดำเนินการโดยใช้นิพจน์การแคสต์แทน " ( msdn .microsoft.com / en-us / library / cscsdfbt.aspx )
user1234567

33

ความแตกต่างระหว่างISและAsก็คือ ..

IS - Is Operator ใช้เพื่อตรวจสอบความเข้ากันได้ของวัตถุกับประเภทที่กำหนดและส่งคืนผลลัพธ์เป็นบูลีน (จริงหรือเท็จ)

AS - As Operator ใช้สำหรับการหล่อวัตถุไปยังประเภทหรือคลาสที่กำหนด

อดีต

Student s = obj as Student;

เทียบเท่ากับ:

Student s = obj is Student ? (Student)obj : (Student)null;

1
ความเท่าเทียมกันแสดงให้เห็นอย่างชัดเจนว่าทั้งสองแบบใดมีความดั้งเดิมมากกว่าและรองรับความสัมพันธ์ของพวกเขาอย่างหรูหรา ขอบคุณสำหรับความเท่าเทียม!
Musa Al-hassy

1
@ MusaAl-hassy อันที่จริงสิ่งนี้ไม่ได้แสดงให้เห็นว่าเป็นแบบดั้งเดิมมากกว่า isสามารถแสดงได้ด้วยasและสามารถแสดงได้ด้วยas isนี่คือวิธีที่จะทำให้isกับasคำหลัก Bool b = obj is Student; เทียบเท่ากับ: Bool b = (obj as Student) != null; เพิ่มเติมเกี่ยวกับสิ่งนี้ที่นี่
Alex Telon

8

ทั้งสองisและasคำหลักใช้สำหรับการหล่อแบบใน C #

เมื่อคุณดูรหัส IL ของการใช้งานของคำหลักทั้งสองคำคุณจะได้รับความแตกต่างอย่างง่ายดาย

รหัส C #:

BaseClass baseclassInstance = new DerivedClass();
DerivedClass derivedclassInstance;

if (baseclassInstance is DerivedClass)
{
   derivedclassInstance = (DerivedClass)baseclassInstance;
   // do something on derivedclassInstance
}


derivedclassInstance = baseclassInstance as DerivedClass;

if (derivedclassInstance != null)
{
   // do something on derivedclassInstance
}

รหัส IL (สำหรับรหัส C # ด้านบนอยู่ในภาพที่แนบมา):

รหัส IL สำหรับรหัส C # ด้านบน รหัส IL สำหรับisการใช้คำหลักประกอบด้วยคำแนะนำ IL ทั้งสองและisinsta แต่รหัส IL สำหรับการใช้งานคำหลักมีเพียง.castclass
asisinsta

ในการใช้งานที่กล่าวมาข้างต้นจะมีการพิมพ์สองตัวเกิดขึ้นโดยที่isมีการใช้คำหลักและมีเพียงตัวพิมพ์เดียวที่ใช้asคำหลัก

หมายเหตุ: หากคุณใช้isคีย์เวิร์ดเพื่อตรวจสอบเงื่อนไขบางอย่างและไม่มีความสนใจใด ๆ ในผลลัพธ์การพิมพ์จะมีเพียงตัวพิมพ์เดียวเท่านั้นคือ

if (baseclassInstance is DerivedClass)
{
   // do something based on the condition check.
}

isและasคำหลักจะถูกใช้ตามความจำเป็น


6

คีย์เวิร์ดคือการตรวจสอบว่าค่าทางด้านซ้ายเป็นอินสแตนซ์ของประเภททางด้านขวาหรือไม่ ตัวอย่างเช่น:

if(obj is string)
{
     ...
}

โปรดทราบว่าในกรณีนี้คุณจะต้องใช้การแคสต์ที่ชัดเจนเป็นพิเศษเพื่อให้ obj เป็นสตริง

คีย์เวิร์ด as ใช้ในการส่งประเภท nullable หากค่าที่ระบุไม่ใช่อินสแตนซ์ของชนิดที่ระบุค่า null จะถูกส่งกลับ ตัวอย่างเช่น:

string str = obj as string;
if(str != null)
{
     ...
}

+1 สำหรับ "คำหลัก as ใช้ในการแคสต์ประเภทที่เป็นโมฆะ"
user2330678

3

ฉันจะบอกว่า: อ่าน MSDN ออนไลน์ แต่นี่คือ:

ตัวดำเนินการ is จะตรวจสอบว่าวัตถุเข้ากันได้กับชนิดที่กำหนดหรือไม่และผลลัพธ์ของการประเมินเป็นบูลีน: จริงหรือเท็จ

ตัวดำเนินการ as จะไม่มีข้อยกเว้น


โอเปอเรเตอร์ "as" จะไม่ทิ้งข้อยกเว้นเช่นกันมันจะคืนค่าว่าง
Pinte Dani

แก้ไขการพิมพ์ผิดเกี่ยวกับ 'is' และ 'as'
Patrick Peters

2

เป็นตัวดำเนินการนักแสดงจะส่งคืนจริงหากทำสำเร็จ จะส่งคืนเท็จหากการร่ายล้มเหลว ด้วยเหตุนี้คุณจึงไม่สามารถจับตัวแปรที่แปลงได้ โอเปอเรเตอร์นี้มีประโยชน์มากที่สุดเมื่อตรวจสอบประเภทใน if-statement และ expression is-cast จะเหมาะก็ต่อเมื่อไม่จำเป็นต้องใช้ตัวแปรผลลัพธ์สำหรับการใช้งานต่อไป

ในฐานะนักแสดง ด้วยวิธีนี้เราจะได้รับประสิทธิภาพและหลีกเลี่ยงข้อยกเว้นเมื่อนักแสดงไม่ถูกต้อง Null จะถูกส่งกลับเมื่อไม่สามารถร่ายได้ สำหรับประเภทอ้างอิงแนะนำให้ใช้ as-cast ทั้งรวดเร็วและปลอดภัยเราสามารถทดสอบตัวแปรที่เป็นผลลัพธ์กับ null แล้วใช้งานได้ สิ่งนี้จะกำจัดการร่ายเพิ่มเติม


2
  1. คือตัวดำเนินการตรวจสอบว่าวัตถุเข้ากันได้กับชนิดที่กำหนดผลลัพธ์ขึ้นอยู่กับจริงหรือเท็จ
  2. ตามที่ใช้ในการส่งประเภทหนึ่งไปยังประเภทอื่นและผลการแปลงล้มเหลวเป็นโมฆะยกเว้นจากนั้นเพิ่มข้อยกเว้น ดูลิงค์เพื่อความเข้าใจที่ดีขึ้นพร้อมตัวอย่างhttps://blogs.msdn.microsoft.com/prakasht/2013/04/23/difference-between-direct-casting-is-and-as-operator-in-c/

2

เป็น OPERATOR ตัวดำเนินการ is ใน C # ใช้เพื่อตรวจสอบประเภทวัตถุและส่งคืนค่าบูล: จริงถ้าวัตถุเป็นประเภทเดียวกันและเป็นเท็จถ้าไม่ หรือตัวดำเนินการ“ is” ใช้เพื่อตรวจสอบว่าประเภทรันไทม์ของออบเจ็กต์เข้ากันได้กับประเภทที่กำหนดหรือไม่ สำหรับอ็อบเจ็กต์ null จะส่งกลับเท็จเช่น

if(obj is AnimalObject)
{
 //Then Work
}

เป็น OPERATOR

ตัวดำเนินการ as ทำงานเดียวกันคือตัวดำเนินการ แต่ความแตกต่างแทนที่จะเป็นบูลจะส่งคืนอ็อบเจ็กต์หากเข้ากันได้กับประเภทนั้นมิฉะนั้นจะส่งคืนค่าว่างในคำอื่นตัวดำเนินการ 'as' ใช้เพื่อทำการแปลงระหว่างกัน ประเภท

เช่น

Type obj = Object as Type;

ข้อดีของการ over คือ ในกรณีของ is operator ในการพิมพ์ cast เราต้องทำสองขั้นตอน:

Check the Type using is
If its true then Type cast

จริงๆแล้วสิ่งนี้มีผลต่อประสิทธิภาพเนื่องจากทุกครั้งที่ CLR จะผ่านลำดับชั้นการสืบทอดโดยตรวจสอบแต่ละประเภทฐานกับประเภทที่ระบุ

เพื่อหลีกเลี่ยงปัญหานี้ให้ใช้ as มันจะทำในขั้นตอนเดียว สำหรับการตรวจสอบประเภทเท่านั้นที่เราควรใช้ตัวดำเนินการ is


การตอบคำถามอายุ 8 ปีที่มีคำตอบที่ถูกต้องมากมายไม่ใช่วิธีที่ดีที่สุดในการใช้ Stack Overflow
Claus Jørgensen

1

ตัวดำเนินการ As นั้นคล้ายกับ cast แต่จะส่งคืนค่าว่างแทนข้อยกเว้นหากล้มเหลว

และตัวดำเนินการ Is ใช้เพื่อตรวจสอบว่าวัตถุหนึ่งเข้ากันได้กับบางประเภทหรือไม่ โดยปกติจะใช้ในคำสั่ง If


1

is: ตัวดำเนินการ is ใช้เพื่อตรวจสอบว่าชนิดรันไทม์ของออบเจ็กต์เข้ากันได้กับประเภทที่กำหนดหรือไม่

as: ตัวดำเนินการ as ใช้เพื่อทำการแปลงระหว่างประเภทที่เข้ากันได้

object s = "this is a test";
string str=string.Empty;
if( s is string)
    str = s as string;

2
คำตอบของคุณถูกต้อง แต่โค้ดตัวอย่างของคุณเป็นรูปแบบต่อต้าน มันแพงที่จะทำisแล้วasมัน unboxes สองครั้ง สำหรับประเภทการอ้างอิงคุณควรทำasจากนั้นตรวจสอบค่าว่างเพื่อดูว่าใช้งานได้หรือไม่
Steven Sudit

1

ดูวิดีโอ youtube ด้านล่างซึ่งอธิบายถึงความแตกต่างในรูปแบบการสาธิตและเป็นภาพมากขึ้น: -

https://www.youtube.com/watch?v=IKmRtJcRX_I

ด้านล่างนี้เป็นคำตอบยาวพร้อมคำอธิบายรหัส

คีย์เวิร์ด“ IS” มีประโยชน์ในการตรวจสอบว่าวัตถุเข้ากันได้กับประเภทหรือไม่ ตัวอย่างเช่นในโค้ดด้านล่างเรากำลังตรวจสอบว่าออบเจ็กต์“ ocust” เป็นประเภทของคลาส“ ลูกค้า” หรือไม่

object ocust = new Customer();

if (ocust is Customer)
{ 

คำหลัก“ AS” ช่วยในการแปลงจากประเภทหนึ่งไปเป็นประเภทอื่น ตัวอย่างเช่นในโค้ดด้านล่างเรากำลังแปลงวัตถุเป็นประเภทข้อมูลสตริง หากคีย์เวิร์ด“ AS” ไม่สามารถพิมพ์ cast ได้จะส่งกลับค่า NULL

object o = "somestring";
string str = o as string;

1
MyClass myObject = (MyClass) obj;

VS

MyClass myObject = obj as MyClass;

อย่างที่สองจะคืนค่า null หาก obj ไม่ใช่ MyClass แทนที่จะโยนข้อยกเว้นการร่ายคลาส

จะคืนค่าจริงหรือเท็จเท่านั้น


1

ทั้ง IS และ AS ใช้สำหรับ Safe Type Casting

IS Keyword -> ตรวจสอบว่าประเภทของวัตถุที่กำหนดเข้ากันได้กับประเภทวัตถุใหม่หรือไม่ มันไม่เคยมีข้อยกเว้น นี่คือประเภทบูลีน .. ส่งกลับว่าจริงหรือเท็จ

`student stud = new student(){}
if(stud is student){} // It returns true // let say boys as derived class
if(stud is boys){}// It returns false since stud is not boys type
 //this returns true when,
student stud = new boys() // this return true for both if conditions.`

AS Keyword: ตรวจสอบว่าประเภทของวัตถุที่กำหนดเข้ากันได้กับประเภทวัตถุใหม่หรือไม่ มันจะส่งคืนค่าที่ไม่เป็นค่าว่างหากวัตถุที่กำหนดเข้ากันได้กับวัตถุใหม่มิฉะนั้นจะเป็นโมฆะ .. สิ่งนี้จะทำให้เกิดข้อยกเว้น

`student stud = new student(){}
 // let say boys as derived class
boys boy = stud as boys;//this returns null since we cant convert stud type from base class to derived class
student stud = new boys()
boys boy = stud as boys;// this returns not null since the obj is pointing to derived class`

1

ตัวดำเนินการทั้งสองใช้สำหรับการหล่อแบบปลอดภัย

เป็นผู้ดำเนินการ:

ตัวดำเนินการ AS ยังตรวจสอบว่าชนิดของวัตถุที่กำหนดเข้ากันได้กับประเภทวัตถุใหม่หรือไม่ คีย์เวิร์ดนี้จะตรวจสอบว่าประเภทของอ็อบเจ็กต์ที่กำหนดเข้ากันได้กับอ็อบเจ็กต์ประเภทใหม่หรือไม่ หากเข้ากันไม่ได้กับอันใหม่ก็จะคืนค่า NULL

เป็นผู้ดำเนินการ:

ตัวดำเนินการนี้ตรวจสอบว่าประเภทของวัตถุเข้ากันได้กับวัตถุใหม่หรือไม่ ถ้ามันเข้ากันได้มันจะส่งคืนจริงหรือเท็จ


ไม่คิดว่าจะสายไปหน่อยเหรอเหมือน 4 ปี?
Soner Gönül

โอ้ใช่ ... ขออภัย .... ฉันเพิ่งเริ่มใช้ stackoverflow จึงออกไปเล็กน้อย ... ไม่ได้สังเกตวันที่โพสต์ ...
Tukaram

การมีส่วนร่วมคือการสนับสนุน! ขอขอบคุณที่ระบุคีย์เวิร์ด "Safe typecasting"! :-)
Musa Al-hassy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.