ฉันต้องการแปลงสตริงเป็นประเภททั่วไปเช่นint
หรือdate
หรือlong
ตามประเภทการส่งคืนทั่วไป
โดยทั่วไปฟังก์ชั่นเหมือนที่ส่งกลับรายการของการพิมพ์ Parse<T>(String)
T
ตัวอย่างเช่นถ้า int ถูกส่งผ่านฟังก์ชันควรทำint.parse
ภายใน
ฉันต้องการแปลงสตริงเป็นประเภททั่วไปเช่นint
หรือdate
หรือlong
ตามประเภทการส่งคืนทั่วไป
โดยทั่วไปฟังก์ชั่นเหมือนที่ส่งกลับรายการของการพิมพ์ Parse<T>(String)
T
ตัวอย่างเช่นถ้า int ถูกส่งผ่านฟังก์ชันควรทำint.parse
ภายใน
คำตอบ:
ตามตัวอย่างของคุณคุณสามารถทำได้:
int i = (int)Convert.ChangeType("123", typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("2009/12/12", typeof(DateTime));
เพื่อให้เป็นไปตามข้อกำหนด "ประเภทการคืนสินค้าทั่วไป" คุณสามารถเขียนวิธีการขยายของคุณเอง:
public static T ChangeType<T>(this object obj)
{
return (T)Convert.ChangeType(obj, typeof(T));
}
สิ่งนี้จะช่วยให้คุณทำ:
int i = "123".ChangeType<int>();
IConvertable
คุณไม่ควรบังคับT
ด้วยเช่นกันT ChangeType<T>(this object obj) where T : IConvertable
?
obj
ต้องเป็นอย่างIConvertible
นั้น แต่ไม่มีทางระบุได้ในเวลาคอมไพล์
ดูเหมือนว่าฉันจะสายเกินไปที่จะตอบกระทู้นี้ แต่นี่คือการใช้งานของฉัน:
โดยพื้นฐานแล้วฉันได้สร้างเมธอด Extention สำหรับคลาส Object มันจัดการทุกประเภทเช่น nullable คลาสและโครงสร้าง
public static T ConvertTo<T>(this object value)
{
T returnValue;
if (value is T variable)
returnValue = variable;
else
try
{
//Handling Nullable types i.e, int?, double?, bool? .. etc
if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
returnValue = (T) conv.ConvertFrom(value);
}
else
{
returnValue = (T) Convert.ChangeType(value, typeof(T));
}
}
catch (Exception)
{
returnValue = default(T);
}
return returnValue;
}
TypeDescriptor
สำหรับประเภทที่เป็นโมฆะและConvert.ChangeType
สำหรับประเภทที่ไม่เป็นโมฆะ try
บล็อกทั้งหมดนี้สามารถลดลงเหลือเพียงTypeConverter
2 บรรทัดของโค้ดและจะใช้ได้กับทั้งสองอย่างเป็นโมฆะและไม่เป็นโมฆะ
System.Convert.ChangeType
ไม่แปลงเป็นประเภทใด ๆ คิดดังต่อไปนี้:
การแปลงเหล่านี้เป็นไปได้ด้วยการใช้ ChangeTypeนี้
คำตอบของ Pranayเวอร์ชันที่สะอาดกว่า
public static T ConvertTo<T>(this object value)
{
if (value is T variable) return variable;
try
{
//Handling Nullable types i.e, int?, double?, bool? .. etc
if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
}
return (T)Convert.ChangeType(value, typeof(T));
}
catch (Exception)
{
return default(T);
}
}
มีอนุสัญญาสองสามข้อใน. NET เพื่อแปลงวัตถุประเภทหนึ่งเป็นอีกประเภทหนึ่ง
แต่วิธีการเหล่านี้ช้ากว่าปกติของคุณT.Parse(string)
มากทำให้เกิดการชกมวยและเกี่ยวข้องกับการจัดสรรจำนวนมากในแต่ละครั้งที่คุณต้องการแปลงค่าเดียว
สำหรับValueStringฉันเลือกที่จะหาวิธีการแยกวิเคราะห์แบบคงที่ที่เหมาะสมโดยใช้การสะท้อนกลับสร้างนิพจน์แลมบ์ดาที่เรียกมันและแคชตัวแทนที่คอมไพล์แล้วเพื่อใช้ในอนาคต (ดูตัวอย่างคำตอบนี้ )
นอกจากนี้ยังเปลี่ยนกลับไปใช้วิธีที่ฉันกล่าวถึงข้างต้นหากประเภทไม่มีวิธีการแยกวิเคราะห์ที่เหมาะสม (ดูส่วนประสิทธิภาพใน readme)
var v = new ValueString("15"); // struct
var i = v.As<int>(); // Calls int.Parse.