นี่อาจเป็นเรื่องเล็กน้อย แต่ฉันไม่สามารถคิดวิธีที่ดีกว่าที่จะทำ ฉันมีวัตถุ COM ที่คืนค่าตัวแปรซึ่งกลายเป็นวัตถุใน C # วิธีเดียวที่ฉันจะได้รับสิ่งนี้คือ int
int test = int.Parse(string.Format("{0}", myobject))
มีวิธีที่สะอาดกว่านี้หรือไม่? ขอบคุณ
นี่อาจเป็นเรื่องเล็กน้อย แต่ฉันไม่สามารถคิดวิธีที่ดีกว่าที่จะทำ ฉันมีวัตถุ COM ที่คืนค่าตัวแปรซึ่งกลายเป็นวัตถุใน C # วิธีเดียวที่ฉันจะได้รับสิ่งนี้คือ int
int test = int.Parse(string.Format("{0}", myobject))
มีวิธีที่สะอาดกว่านี้หรือไม่? ขอบคุณ
คำตอบ:
คุณมีหลายทางเลือก:
(int)
- ผู้ประกอบการหล่อ ใช้งานได้ถ้าวัตถุนั้นเป็นจำนวนเต็มในบางระดับในลำดับชั้นการสืบทอดหรือหากมีการกำหนดการแปลงโดยนัย
int.Parse()/int.TryParse()
- สำหรับการแปลงจากสตริงของรูปแบบที่ไม่รู้จัก
int.ParseExact()/int.TryParseExact()
- สำหรับการแปลงจากสตริงในรูปแบบเฉพาะ
Convert.ToInt32()
- สำหรับการแปลงวัตถุประเภทที่ไม่รู้จัก มันจะใช้การแปลงที่ชัดเจนและโดยนัยหรือการใช้งาน IConvertible หากมีการกำหนดไว้
as int?
- หมายเหตุเครื่องหมาย "?" as
ผู้ประกอบการเป็นเพียงสำหรับประเภทของการอ้างอิงและดังนั้นผมจึงใช้ "?" Nullable<int>
จะมีความหมายว่า "การas
ดำเนินการ" ทำงานเหมือนConvert.To____()
แต่คิดว่าTryParse()
แทนที่จะParse()
: มันกลับnull
มากกว่าการขว้างปายกเว้นถ้าแปลงล้มเหลว
ของเหล่านี้ฉันต้องการ(int)
ถ้าวัตถุเป็นเพียงจำนวนเต็มชนิดบรรจุกล่อง มิฉะนั้นจะใช้Convert.ToInt32()
ในกรณีนี้
โปรดทราบว่านี่เป็นคำตอบทั่วไปมาก: ฉันต้องการที่จะให้ความสนใจกับคำตอบของดาร์เรนคลาร์กเพราะฉันคิดว่ามันทำงานได้ดีกับข้อมูลเฉพาะที่นี่ แต่มาช้าและยังไม่ได้รับการโหวต เขาได้รับการโหวตของฉันสำหรับ "คำตอบที่ยอมรับ" อย่างไรก็ตามสำหรับคำแนะนำ (int) สำหรับการชี้ให้เห็นว่าถ้ามันล้มเหลว(int)(short)
อาจทำงานได้แทนและสำหรับการแนะนำให้คุณตรวจสอบดีบักเกอร์ของคุณเพื่อค้นหาประเภทรันไทม์ที่แท้จริง
นักแสดง(int) myobject
ควรจะทำงาน
หากนั่นทำให้คุณมีข้อยกเว้นการส่งที่ไม่ถูกต้องอาจเป็นเพราะประเภทของตัวแปรไม่ใช่ VT_I4 เดิมพันของฉันคือตัวแปรที่มี VT_I4 ถูกแปลงเป็น int ชนิดบรรจุกล่อง VT_I2 เป็นชนิดบรรจุกล่องแบบสั้นเป็นต้น
เมื่อทำการร่ายบนชนิดค่าชนิดบรรจุกล่องจะใช้การร่ายแบบนั้นกับชนิดแบบบรรจุกล่องเท่านั้น ตัวอย่างของศัตรูถ้าตัวแปรที่ส่งคืนมาเป็น VT_I2 จริง ๆ แล้ว(int) (short) myObject
ควรใช้งานได้
วิธีที่ง่ายที่สุดในการค้นหาคือตรวจสอบวัตถุที่ส่งคืนและดูประเภทของวัตถุนั้นในตัวดีบั๊ก นอกจากนี้ตรวจสอบให้แน่ใจว่าในแอสเซมบลี interop คุณมีเครื่องหมายส่งคืนค่าด้วยMarshalAs(UnmanagedType.Struct)
Convert.ToInt32 (MyObject);
กรณีนี้จะจัดการกับกรณีที่ myobject เป็นโมฆะและส่งคืน 0 แทนที่จะโยนข้อยกเว้น
ToInt32
มันจะทำงานเฉพาะถ้าใช้เช่น
ใช้Int32.TryParse
ดังนี้
int test;
bool result = Int32.TryParse(value, out test);
if (result)
{
Console.WriteLine("Sucess");
}
else
{
if (value == null) value = "";
Console.WriteLine("Failure");
}
ฉันแสดงความแตกต่างในแต่ละวิธีการคัดเลือก การหล่อแบบพิเศษนั้นจัดการกับอะไรและไม่ได้?
// object to int
// does not handle null
// does not handle NAN ("102art54")
// convert value to integar
int intObj = (int)obj;
// handles only null or number
int? nullableIntObj = (int?)obj; // null
Nullable<int> nullableIntObj1 = (Nullable<int>)obj; // null
// best way for casting from object to nullable int
// handles null
// handles other datatypes gives null("sadfsdf") // result null
int? nullableIntObj2 = obj as int?;
// string to int
// does not handle null( throws exception)
// does not string NAN ("102art54") (throws exception)
// converts string to int ("26236")
// accepts string value
int iVal3 = int.Parse("10120"); // throws exception value cannot be null;
// handles null converts null to 0
// does not handle NAN ("102art54") (throws exception)
// converts obj to int ("26236")
int val4 = Convert.ToInt32("10120");
// handle null converts null to 0
// handle NAN ("101art54") converts null to 0
// convert string to int ("26236")
int number;
bool result = int.TryParse(value, out number);
if (result)
{
// converted value
}
else
{
// number o/p = 0
}
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
Convert.ChangeType
ได้ ฉันจะบอกว่าอาจไม่ใช่คำตอบที่สมบูรณ์แบบสำหรับ OP แต่มันมีประโยชน์กับบางคน!
จาก MSDN:
private static void TryToParse(string value)
{
int number;
bool result = Int32.TryParse(value, out number);
if (result)
{
Console.WriteLine("Converted '{0}' to {1}.", value, number);
}
else
{
if (value == null) value = "";
Console.WriteLine("Attempted conversion of '{0}' failed.", value);
}
}
แปลก แต่คำตอบที่ยอมรับนั้นดูเหมือนว่าผิดเกี่ยวกับการส่งและการแปลงในค่าเฉลี่ยที่ได้จากการทดสอบของฉันและการอ่านเอกสารด้วยเช่นกันไม่ควรคำนึงถึงตัวดำเนินการที่ชัดเจนหรือโดยนัย
ดังนั้นถ้าฉันมีตัวแปรชนิดวัตถุและคลาส "ชนิดบรรจุกล่อง" มีตัวดำเนินการบางอย่างที่กำหนดไว้พวกมันจะไม่ทำงาน
อีกวิธีที่ง่าย แต่การคิดต้นทุนที่มีประสิทธิภาพจริงๆคือการสร้างมาก่อนในแบบไดนามิก
(int) (ไดนามิก) myObject
คุณสามารถลองได้ในหน้าต่างโต้ตอบของ VS
public class Test
{
public static implicit operator int(Test v)
{
return 12;
}
}
(int)(object)new Test() //this will fail
Convert.ToInt32((object)new Test()) //this will fail
(int)(dynamic)(object)new Test() //this will pass
dynamic
อยู่ไกลจากฟรี
int i = myObject.myField.CastTo<int>();