Saya dapat menelepon Get<int>(Stat);
atauGet<string>(Name);
Tetapi ketika menyusun saya mendapatkan:
Tidak dapat secara implisit mengubah tipe 'int' menjadi 'T'
dan hal yang sama untuk string
.
public T Get<T>(Stats type) where T : IConvertible
{
if (typeof(T) == typeof(int))
{
int t = Convert.ToInt16(PlayerStats[type]);
return t;
}
if (typeof(T) == typeof(string))
{
string t = PlayerStats[type].ToString();
return t;
}
}
Jawaban:
Setiap kali Anda menemukan diri Anda beralih pada tipe generik, Anda hampir pasti melakukan sesuatu yang salah . Generik harus generik ; mereka harus beroperasi secara identik sepenuhnya terlepas dari jenisnya .
Jika T hanya bisa berupa int atau string maka jangan menulis kode Anda dengan cara ini sama sekali. Tulis dua metode, satu yang mengembalikan int dan satu lagi yang mengembalikan string.
sumber
int, int?, bool, bool?, string
, dan sepertinya tidak mungkin.Anda seharusnya dapat menggunakan
Convert.ChangeType()
alih-alih kode khusus Anda:public T Get<T>(Stats type) where T : IConvertible { return (T) Convert.ChangeType(PlayerStats[type], typeof(T)); }
sumber
return (T)(object)PlayerStats[type];
public T Get<T>(Stats type ) where T : IConvertible { if (typeof(T) == typeof(int)) { int t = Convert.ToInt16(PlayerStats[type]); return (T)t; } if (typeof(T) == typeof(string)) { string t = PlayerStats[type].ToString(); return (T)t; } }
sumber
return (T) t;
karena tidak diperlukan pemeriksaan nol.ChangeType
mungkin adalah pilihan terbaik Anda. Solusi saya mirip dengan yang disediakan oleh BrokenGlass dengan sedikit logika coba tangkap.static void Main(string[] args) { object number = "1"; bool hasConverted; var convertedValue = DoConvert<int>(number, out hasConverted); Console.WriteLine(hasConverted); Console.WriteLine(convertedValue); } public static TConvertType DoConvert<TConvertType>(object convertValue, out bool hasConverted) { hasConverted = false; var converted = default(TConvertType); try { converted = (TConvertType) Convert.ChangeType(convertValue, typeof(TConvertType)); hasConverted = true; } catch (InvalidCastException) { } catch (ArgumentNullException) { } catch (FormatException) { } catch (OverflowException) { } return converted; }
sumber
Coba ini:
public T Get<T>(Stats type ) where T : IConvertible { if (typeof(T) == typeof(int)) { return (T)(object)Convert.ToInt16(PlayerStats[type]); } if (typeof(T) == typeof(string)) { return (T)(object)PlayerStats[type]; } }
sumber
Sebenarnya, Anda dapat mengubahnya menjadi
object
dan kemudian menjadiT
.T var = (T)(object)42;
Contoh untuk
bool
:public class Program { public static T Foo<T>() { if(typeof(T) == typeof(bool)) { return (T)(object)true; } return default(T); } public static void Main() { bool boolValue = Foo<bool>(); // == true string stringValue = Foo<string>(); // == null } }
Terkadang, perilaku ini diinginkan. Misalnya, saat mengimplementasikan atau mengganti metode umum dari kelas atau antarmuka dasar dan Anda ingin menambahkan beberapa fungsi berbeda berdasarkan
T
tipenya.sumber
Mengingat logika @BrokenGlass (
Convert.ChangeType
) tidak mendukung tipe GUID.public T Get<T>(Stats type) where T : IConvertible { return (T) Convert.ChangeType(PlayerStats[type], typeof(T)); }
Kesalahan : Transmisi tidak valid dari 'System.String' ke 'System.Guid'.
Sebagai gantinya, gunakan logika di bawah ini
TypeDescriptor.GetConverter
dengan menambahkanSystem.ComponentModel
namespace.public T Get<T>(Stats type) where T : IConvertible { (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromInvariantString(PlayerStats[type]) }
Baca ini .
sumber
Sepertinya Anda memerlukan
TypeConverter
, lihat entri blog ini .sumber
Anda cukup melakukan cast seperti di bawah ini,
public T Get<T>(Stats type) where T : IConvertible { if (typeof(T) == typeof(int)) { int t = Convert.ToInt16(PlayerStats[type]); return t as T; } if (typeof(T) == typeof(string)) { string t = PlayerStats[type].ToString(); return t as T; } }
sumber