Dizede ve genel türde geçmek istediğim şu senaryoyu kullanıyorum:TryParse() genel bir sürümünde belirli bir türe nasıl dönüştürebilirim?
public class Worker {
public void DoSomeWork<T>(string value)
where T : struct, IComparable<T>, IEquatable<T> { ... }
}
Bir noktada dize değerini T
değerine dönüştürmem gerekiyor. Ancak dize T
türüne dönüştürülemezse mantık yürütmem gerektiğinden düz bir dönüştürme yapmak istemiyorum.
Convert.ChangeType()
kullanmayı deneyebileceğimi düşünüyordum ama bu, eğer dönüştürmezse bir istisna atar ve DoSomeWork()
yöntemini çalıştırmaya/denemeye gerek duymayacak kadar sık çalıştıracağım problemi vardır. dönüştürmenin geçerli olup olmadığını belirlemek için.
Bu beni düşünerek, sayısal tiplerle çalışacağımı biliyorum, bu yüzden T aşağıdakilerden biri olacaktır: int
, uint
, short
, ushort
, long
, ulong
, byte
, sbyte
, decimal
, float
, double
. Bunu bildiğim için, sayısal türleri kullanacağımı bildiğim gerçeğiyle çalışarak daha hızlı bir çözüm bulmak mümkün olabileceğini düşündüm (T
, bir istisna atarım sayısal bir tür değilse). Xzx95
public class NumericWorker {
public void DoSomeWork<T>(string value)
where T : struct, IComparable<T>, IEquatable<T>
{
ParseDelegate<T> tryConverter =
SafeConvert.RetreiveNumericTryParseDelegate<T>();
...
}
}
public class SafeConvert
{
public delegate bool ParseDelegate<T>(string value, out T result);
public static ParseDelegate<T> RetreiveNumericTryParseDelegate<T>()
where T : struct, IComparable<T>, IEquatable<T>
{
ParseDelegate<T> tryParseDelegate = null;
if (typeof(T) == typeof(int))
{
tryParseDelegate = (string v, out T t) =>
{
int typedValue;
bool result = int.TryParse(v, out typedValue);
t = result ? (T)typedValue : default(T);
//(T)Convert.ChangeType(typedValue, typeof(T)) : default(T);
return result;
};
}
else if (typeof(T) == typeof(uint)) { ... }
else if (typeof(T) == typeof(short)) { ... }
else if (typeof(T) == typeof(ushort)) { ... }
else if (typeof(T) == typeof(long)) { ... }
else if (typeof(T) == typeof(ulong)) { ... }
else if (typeof(T) == typeof(byte)) { ... }
else if (typeof(T) == typeof(sbyte)) { ... }
else if (typeof(T) == typeof(decimal)) { ... }
else if (typeof(T) == typeof(float)) { ... }
else if (typeof(T) == typeof(double)) { ... }
return tryParseDelegate;
}
}
Ancak t = result ? (T)typedValue : default(T);
typedValue
için T
'e neden olarak sorunlara neden olan t = result ? (T)typedValue : default(T);
yazamadığım problemler var ve şu ana kadar etrafta dolaşabildiğim tek yol (T)Convert.ChangeType(typedValue, typeof(T))
yazıyor. Ama eğer bunu yaparsam başka bir dönüşüm yapıyorum.
Bu yüzden, bu sorunu nasıl çözebileceğimi (ChangeType()
'yi yapmayı düşünüyorsanız bir sorun olduğunu düşünüyorsanız) veya daha önce hiç düşünmediğim daha iyi bir çözüm olup olmadığını bilip bilmediğimi merak ediyordum.
ne thats neden ben çünkü/catch changetype kullanmak ve denemek istemiyordu bu yüzden :(... kullanıcı girişini doğruluyor için kullanıyorum kullanıcının ne yazacağını bilen… –
Heh, tamam :-) FWIW, 'ChangeType() 'tarafından atılan özel durumların verimlilik açısından çok fazla endişelenmem. stil sonra çözümünüz iyi görünüyor. Muhtemelen API'yi tek bir genel yönteme kadar kaynatıp, dışarıdan 'out' parametresi tarafından gizli olarak belirtilebileceğini unutmayın. – Shog9
Her şey basitlik için, "T parametresi tarafından örtülü olarak belirtilir" ile ne demek istiyorsunuz? –