Tôi có một số mã (trong đó hoạt động tốt) mà trông giống như sau:Làm cách nào tôi có thể sử dụng phản chiếu để chuyển đổi từ int sang thập phân?
int integer = 42;
decimal? castTo = integer;
Sau đó, tôi muốn làm một cái gì đó tương tự với phản ánh, với một số mã trông như thế này:
object value = source; // source was an int originally
var parameters = new object[1];
...
parameters[0] = value;
var setMethod = property.GetSetMethod();
// Call the set method, which takes a decimal? as a parameter
setMethod.Invoke(o, parameters);
Khi Tôi thực hiện việc này, tôi nhận được:
failed: System.ArgumentException : Object of type 'System.Int32' cannot be converted to type 'System.Nullable`1[System.Decimal]'.
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
Tại sao chuyển đổi loại tiềm ẩn hoạt động tốt ở những nơi khác không phản ánh? Có một mẹo để sử dụng sự phản chiếu để thực hiện chuyển đổi này không?
Chỉnh sửa: Cảm ơn tất cả các câu trả lời. Đây là giải pháp tôi đã đưa ra, dựa trên những câu trả lời:
private object Convert(object source, Type destinationType)
{
if (source == null)
{
return null;
}
var sourceType = source.GetType();
// unwrap nullable types
var nullableType = Nullable.GetUnderlyingType(destinationType);
if(nullableType != null)
{
destinationType = nullableType;
}
nullableType = Nullable.GetUnderlyingType(sourceType);
if(nullableType != null)
{
sourceType = nullableType;
}
var implicitCastMethod =
destinationType.GetMethod("op_Implicit",
new[] { sourceType });
if(implicitCastMethod == null)
{
return null;
}
return implicitCastMethod.Invoke(null, new[] { source });
}
Chỉnh sửa # 2: Tôi muốn ai đó đã đề cập System.Convert.ChangeType()
, mà xử lý những trường hợp này, và nhiều hơn nữa. Nó chỉ ra rằng op_Implicit
chỉ có thể chuyển đổi thành kiểu số ít hạn chế hơn. (của khóa học, do đó "Ẩn" trong tên). Nói cách khác, giải pháp đầu tiên hoạt động cho int
→ decimal?
nhưng không phải decimal?
→ int
. (Có vẻ như rằng tôi sẽ cần phải thay đổi mã này cũng thử op_Explicit
nếu diễn viên tiềm ẩn thất bại, nếu tôi muốn để có thể xử lý một chuyển đổi từ decimal?
trở lại int
.)
Kể từ System.Convert.ChangeType()
không làm việc với Nullable<>
loại, cuối cùng tôi đã kết thúc bằng một số mã tương tự như những gì tôi tìm thấy here (chút thay đổi):
private static object Convert(object source, Type destinationType)
{
if(destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
if(destinationType.IsGenericType &&
destinationType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (source == null)
{
return null;
}
destinationType = Nullable.GetUnderlyingType(destinationType);
}
return System.Convert.ChangeType(source, destinationType);
}
Đây là những gì cơ bản làm việc cho tôi. Ít nhất nó đã cho tôi đi đúng hướng. Cảm ơn! – mpontillo
'MethodInfo method = source.GetType(). GetMethod (" op_Implicit ");' dễ đọc hơn tìm kiếm lặp lại rõ ràng. –
@Merlyn, vâng, bạn sẽ nhận thấy đó là những gì tôi đã làm nếu bạn đọc chỉnh sửa đầu tiên của tôi, ngoại trừ tôi cũng đã thêm loại vào cuộc gọi GetMethod() là tốt. Nếu không, nếu có nhiều phương thức quá tải op_Implicit, tôi nghĩ rằng tôi vẫn sẽ phải lặp lại? – mpontillo