यह एक उदाहरण के लिए थोड़ा लंबा-ईश है, लेकिन यह अपेक्षाकृत मजबूत दृष्टिकोण है, और अज्ञात मूल्य से अज्ञात प्रकार के लिए कास्टिंग के कार्य को अलग करता है
मेरे पास एक ट्राइकास्ट विधि है जो कुछ इसी तरह का काम करती है, और अशक्त प्रकारों को ध्यान में रखती है।
public static bool TryCast<T>(this object value, out T result)
{
var type = typeof (T);
// If the type is nullable and the result should be null, set a null value.
if (type.IsNullable() && (value == null || value == DBNull.Value))
{
result = default(T);
return true;
}
// Convert.ChangeType fails on Nullable<T> types. We want to try to cast to the underlying type anyway.
var underlyingType = Nullable.GetUnderlyingType(type) ?? type;
try
{
// Just one edge case you might want to handle.
if (underlyingType == typeof(Guid))
{
if (value is string)
{
value = new Guid(value as string);
}
if (value is byte[])
{
value = new Guid(value as byte[]);
}
result = (T)Convert.ChangeType(value, underlyingType);
return true;
}
result = (T)Convert.ChangeType(value, underlyingType);
return true;
}
catch (Exception ex)
{
result = default(T);
return false;
}
}
बेशक TryCast एक प्रकार का पैरामीटर के साथ एक विधि है, इसलिए इसे गतिशील रूप से कॉल करने के लिए आपको MethodInfo का निर्माण स्वयं करना होगा:
var constructedMethod = typeof (ObjectExtensions)
.GetMethod("TryCast")
.MakeGenericMethod(property.PropertyType);
फिर वास्तविक संपत्ति मूल्य निर्धारित करने के लिए:
public static void SetCastedValue<T>(this PropertyInfo property, T instance, object value)
{
if (property.DeclaringType != typeof(T))
{
throw new ArgumentException("property's declaring type must be equal to typeof(T).");
}
var constructedMethod = typeof (ObjectExtensions)
.GetMethod("TryCast")
.MakeGenericMethod(property.PropertyType);
object valueToSet = null;
var parameters = new[] {value, null};
var tryCastSucceeded = Convert.ToBoolean(constructedMethod.Invoke(null, parameters));
if (tryCastSucceeded)
{
valueToSet = parameters[1];
}
if (!property.CanAssignValue(valueToSet))
{
return;
}
property.SetValue(instance, valueToSet, null);
}
और property.CanAssignValue से निपटने के लिए विस्तार विधियाँ ...
public static bool CanAssignValue(this PropertyInfo p, object value)
{
return value == null ? p.IsNullable() : p.PropertyType.IsInstanceOfType(value);
}
public static bool IsNullable(this PropertyInfo p)
{
return p.PropertyType.IsNullable();
}
public static bool IsNullable(this Type t)
{
return !t.IsValueType || Nullable.GetUnderlyingType(t) != null;
}