使用reflection动态地将属性转换为其实际类型

我需要动态地将属性转换为其实际类型。 我如何/可以使用reflection来做到这一点?

解释我正在努力的真实场景。 我试图在Entity Framework属性上调用“First”扩展方法。 要在Framework上下文对象上调用的特定属性作为字符串传递给方法(以及要检索的记录的id)。 所以我需要对象的实际类型才能调用First方法。

我不能在对象上使用“Where”方法,因为lambda或delegate方法仍然需要对象的实际类型才能访问属性。

此外,当对象由entity framework生成时,我无法将类型转换为接口并对其进行操作。

这是场景代码:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Reflection; namespace NmSpc { public class ClassA { public int IntProperty { get; set; } } public class ClassB { public ClassA MyProperty { get; set; } } public class ClassC { static void Main(string[] args) { ClassB tester = new ClassB(); PropertyInfo propInfo = typeof(ClassB).GetProperty("MyProperty"); //get a type unsafe reference to ClassB`s property Object property = propInfo.GetValue(tester, null); //get the type safe reference to the property ClassA typeSafeProperty = property as ClassA; //I need to cast the property to its actual type dynamically. How do I/Can I do this using reflection? //I will not know that "property" is of ClassA apart from at runtime } } } 

 public object CastPropertyValue(PropertyInfo property, string value) { if (property == null || String.IsNullOrEmpty(value)) return null; if (property.PropertyType.IsEnum) { Type enumType = property.PropertyType; if (Enum.IsDefined(enumType, value)) return Enum.Parse(enumType, value); } if (property.PropertyType == typeof(bool)) return value == "1" || value == "true" || value == "on" || value == "checked"; else if (property.PropertyType == typeof(Uri)) return new Uri(Convert.ToString(value)); else return Convert.ChangeType(value, property.PropertyType); } 

我有一些时间,所以我尝试使用VS2010来解决我的问题,我认为我之前是正确的,但我认为动态关键字会“解决”我的问题。 请参阅下面的代码。

 using System.Reflection; namespace TempTest { public class ClassA { public int IntProperty { get; set; } } public class ClassB { public ClassB() { MyProperty = new ClassA { IntProperty = 4 }; } public ClassA MyProperty { get; set; } } public class Program { static void Main(string[] args) { ClassB tester = new ClassB(); PropertyInfo propInfo = typeof(ClassB).GetProperty("MyProperty"); //get a type unsafe reference to ClassB`s property dynamic property = propInfo.GetValue(tester, null); //casted the property to its actual type dynamically int result = property.IntProperty; } } } 

获得reflection类型后,可以使用Convert.ChangeType()

拥有特定类型的变量实际上仅在编译时有用,并且在运行时不会以这种方式使用它。 尝试编写你将利用它的代码…你会发现它不断推动要求知道在某个级别编译时间的类型(可能在调用链的更上方,但你最终还是需要输入具体类型为此有用)。

但要注意的一件事是 – 如果您的类型是引用类型,则该对象仍然是您创建的类型。 将对象保存为类型与对象相比,这并不是一件好事。 这是反思之美(以及它起作用的部分原因)。 实际上没有理由尝试在演员表中“改变”它的类型,因为它仍然是一个对象。

虽然我应该解决现实世界的问题。

 string objectType = "MyProperty"; using (MyEntitiesContext entitiesContext = new MyEntitiesContext()) { try { string queryString = @"SELECT VALUE " + objectType+ " FROM MyEntitiesContext." + objectType + " AS " + objectType + " WHERE " + objectType + ".id = @id"; IQueryable query = entitiesContext.CreateQuery(queryString, new ObjectParameter("id", objectId)); foreach (Object result in query) { return result; } } catch (EntitySqlException ex) { Console.WriteLine(ex.ToString()); } } return null; 

我认为新的CLR4动态关键字可能是“不错”的解决方案。

感谢所有的回应。

如何将根值设置为字符串,然后将其作为字符串携带,直到您需要将其转换为目标类型?

 Type resultType = typeof(T); IEnumerable properties = TypeDescriptor.GetProperties(resultType).Cast(); object instance = Activator.CreateInstance(resultType); var objValue = "VALUE FOR HEADER"; var resultHeader = "HeaderName"; var prop = properties.Single(p => string.Equals(p.Name, resultHeader, StringComparison.InvariantCultureIgnoreCase)); var targetType = Nullable.GetUnderlyingType(prop.PropertyType) !=null Nullable.GetUnderlyingType(prop.PropertyType):prop.PropertyType; objValue = Convert.ChangeType(objValue , targetType); prop.SetValue(instance, objValue ); 

//返回实例;