Tôi có các tình huống sau, nơi tôi muốn vượt qua trong chuỗi và một kiểu generic:Làm cách nào để chuyển đổi thành loại cụ thể trong phiên bản chung của TryParse()?
public class Worker {
public void DoSomeWork<T>(string value)
where T : struct, IComparable<T>, IEquatable<T> { ... }
}
Tại một số điểm dọc theo con đường tôi cần phải chuyển đổi các giá trị chuỗi giá trị T
của nó. Nhưng tôi không muốn làm một chuyển đổi thẳng như tôi cần phải thực hiện một số logic nếu chuỗi không thể được chuyển đổi thành loại T
.
Tôi đã nghĩ rằng tôi có thể thử sử dụng Convert.ChangeType()
nhưng điều này có vấn đề nếu nó không chuyển đổi nó sẽ ném một ngoại lệ và tôi sẽ chạy phương pháp DoSomeWork()
thường đủ để không phải dựa vào một thử/bắt để xác định xem chuyển đổi có hợp lệ hay không.
Vì vậy, đây tôi đã suy nghĩ, tôi biết rằng tôi sẽ làm việc với các loại số, do đó T sẽ được bất kỳ những điều sau đây: int
, uint
, short
, ushort
, long
, ulong
, byte
, sbyte
, decimal
, float
, double
. Biết được điều này tôi nghĩ rằng có thể có một giải pháp nhanh hơn để làm việc với thực tế là tôi biết tôi sẽ sử dụng các loại số (lưu ý nếu T
không phải là loại số tôi ném ngoại lệ) ...
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;
}
}
Nhưng ở trên có vấn đề là tôi không thể viết t = result ? (T)typedValue : default(T);
khi việc tạo typedValue
đến T
gây ra sự cố và cách duy nhất tôi có thể thực hiện được là viết (T)Convert.ChangeType(typedValue, typeof(T))
. Nhưng nếu tôi làm điều này tôi chỉ đang thực hiện một chuyển đổi khác. Vì vậy, tôi đã tự hỏi nếu có ai biết làm thế nào tôi có thể khắc phục vấn đề này (nếu bạn nghĩ rằng làm ChangeType()
là một vấn đề) hoặc nếu có một giải pháp tốt hơn hoàn toàn mà tôi đã không xem xét.
gì tôi đang sử dụng nó cho là xác nhận đầu vào người dùng ... :(do đó, thats lý do tại sao tôi đã không muốn sử dụng changetype và try/catch vì ai biết những gì người dùng sẽ gõ ... –
Heh, ok. :-) FWIW, tôi sẽ không lo lắng quá nhiều về khía cạnh hiệu quả của việc bắt ngoại lệ do 'ChangeType()' đưa ra, nhưng nếu bạn lo lắng về phong cách thì giải pháp của bạn có vẻ ổn. Lưu ý rằng bạn có thể chỉ đơn giản là API bằng cách đun sôi nó xuống một phương thức chung duy nhất, trong đó T được xác định ngầm bởi tham số 'out'. – Shog9
Tôi là tất cả vì sự đơn giản, ý bạn là gì bởi "nơi T được chỉ định ngầm bởi tham số ngoài" ?? –