C# 反射可以';t转换对象
我想使用反射到动态来填充任何类,但当这个类和其他类一样具有属性时,我遇到了问题。在上面的这个例子中,我复制了一部分代码来显示相同的困难。我无法将对象转换为地址 你能帮我吗C# 反射可以';t转换对象,c#,reflection,casting,type-conversion,C#,Reflection,Casting,Type Conversion,我想使用反射到动态来填充任何类,但当这个类和其他类一样具有属性时,我遇到了问题。在上面的这个例子中,我复制了一部分代码来显示相同的困难。我无法将对象转换为地址 你能帮我吗 public class Destinatary { public string DetinataryID { get; set; } public string Name { get; set; } public Address Address { get; set; } } public c
public class Destinatary
{
public string DetinataryID { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Place { get; set; }
public string PostalCode { get; set; }
}
class Program
{
static void Main(string[] args)
{
Destinatary destinataryTest = new Destinatary();
Type type = typeof(Destinatary);
destinataryTest = GenerateDataSample(destinataryTest);
Console.WriteLine($"Name: {destinataryTest.Name}");
Console.WriteLine($"Place: {destinataryTest.Address.PostalCode}");
Console.WriteLine($"City: {destinataryTest.Address.City.Name}");
Console.ReadLine();
}
private static T GenerateDataSample<T>(T classToWork)
{
Type typeToWork = typeof(T);
object tipoInstance = Activator.CreateInstance(typeToWork);
foreach (var classProperty in typeToWork.GetProperties())
{
if (classProperty.PropertyType.FullName.StartsWith("System."))
{
var propertyVal = RandomString(10,false );
classProperty.SetValue(tipoInstance, propertyVal, null);
}
else
{
var instanceIntermediate = Activator.CreateInstance(classProperty.PropertyType);
instanceIntermediate = GenerateDataSample(instanceIntermediate);
classProperty.SetValue(tipoInstance, instanceIntermediate, null); //here there is a probleman (Cant convert Object to Address)
}
}
return (T)tipoInstance;
}
}
公共类目标
{
公共字符串DetinataryID{get;set;}
公共字符串名称{get;set;}
公共广播地址{get;set;}
}
公共课堂演讲
{
公共字符串Place{get;set;}
公共字符串PostalCode{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
Destinatary destinataryTest=新的Destinatary();
类型=类型(目标);
destinataryTest=生成的样本(destinataryTest);
WriteLine($“Name:{destinataryTest.Name}”);
WriteLine($“Place:{destinataryTest.Address.PostalCode}”);
Console.WriteLine($“City:{destinataryTest.Address.City.Name}”);
Console.ReadLine();
}
私有静态T生成的数据样本(T类工作)
{
类型typeToWork=类型(T);
object tipoInstance=Activator.CreateInstance(typeToWork);
foreach(typeToWork.GetProperties()中的var classProperty)
{
if(classProperty.PropertyType.FullName.StartWith(“系统”))
{
var-propertyVal=RandomString(10,false);
SetValue(tipoInstance,propertyVal,null);
}
其他的
{
var instanceIntermediate=Activator.CreateInstance(classProperty.PropertyType);
instanceIntermediate=GenerateDataSample(instanceIntermediate);
classProperty.SetValue(tipoInstance,instanceIntermediate,null);//这里有一个问题(无法将对象转换为地址)
}
}
返回(T)tipoInstance;
}
}
泛型在编译时解析,而不是在运行时解析
在这一行
instanceIntermediate = GenerateDataSample(instanceIntermediate);
object tipoInstance = Activator.CreateInstance(typeToWork);
instanceIntermediate是一个地址对象,但这里的编译器只知道它是一个对象。因此它调用GenerateDataSample,它将在此行中构造一个对象
instanceIntermediate = GenerateDataSample(instanceIntermediate);
object tipoInstance = Activator.CreateInstance(typeToWork);
要生成DataSample并创建对象类ToWork类型的实例,请使用
object tipoInstance = Activator.CreateInstance(classToWork.GetType());
泛型在编译时解析,而不是在运行时解析 在这一行
instanceIntermediate = GenerateDataSample(instanceIntermediate);
object tipoInstance = Activator.CreateInstance(typeToWork);
instanceIntermediate是一个地址对象,但这里的编译器只知道它是一个对象。因此它调用GenerateDataSample,它将在此行中构造一个对象
instanceIntermediate = GenerateDataSample(instanceIntermediate);
object tipoInstance = Activator.CreateInstance(typeToWork);
要生成DataSample并创建对象类ToWork类型的实例,请使用
object tipoInstance = Activator.CreateInstance(classToWork.GetType());
var instanceIntermediate=Activator.CreateInstance(…
)-在这一行上,instanceIntermediate
的编译时类型是object
。因此,当您调用GenerateDataSample(instanceIntermediate)
时,它调用的是GenerateDataSample(instanceIntermediate)
,而不是GenerateDataSample(instanceIntermediate)
如您所料
修正:由于
GenerateDataSample
实际上并不关心输入参数,只关心类型-将其从泛型方法更改为常规方法,采用类型-对象GenerateDataSample(type typeToWork)
-在这一行上,instanceIntermediate
的编译时类型是对象
。因此,当您调用GenerateDataSample(instanceIntermediate)
时,它调用的是GenerateDataSample(instanceIntermediate)
,而不是您可能期望的GenerateDataSample(instanceIntermediate)
修正:因为
GenerateDataSample
实际上并不关心输入参数,只关心类型-将其从泛型方法更改为常规方法,使用类型-对象GenerateDataSample(类型typeToWork)
为什么要转换值?对象已经是Address
类型,并且set方法声明为
public void SetValue (object obj, object value);
i、 例如,它接受类型为object
的变量
调用GenerateDataSample()时出现问题
,因为T
是在编译时确定的,并且instanceIntermediate
的编译时类型是对象
,因此GenerateDataSample
将始终尝试为属性创建类型为System.object
的对象。不要将GenerateDataSample
设为泛型
此外,您实际上不需要向GenerateDataSample
传递实例,只需要传递类型即可
private static object GenerateDataSample(Type typeToWork)
{
object tipoInstance = Activator.CreateInstance(typeToWork);
foreach (PropertyInfo classProperty in typeToWork.GetProperties()) {
object propertyVal;
if (classProperty.PropertyType == typeof(string)) {
propertyVal = RandomString(10, false);
} else {
propertyVal = GenerateDataSample(classProperty.PropertyType);
}
classProperty.SetValue(tipoInstance, propertyVal);
}
return tipoInstance;
}
您还可以创建重载的通用版本:
private static T GenerateDataSample<T>()
{
return (T)GenerateDataSample(typeof(T));
}
private static T GenerateDataSample()
{
返回(T)生成的数据样本(类型(T));
}
然后,您可以使用以下工具创建示例数据:
Destinatary destinataryTest = GenerateDataSample<Destinatary>();
Destinatary destinataryTest=GenerateDataSample();
为什么要转换值?对象已经是地址类型
,并且set方法声明为
public void SetValue (object obj, object value);
i、 例如,它接受类型为object
的变量
调用GenerateDataSample()时出现问题
,因为T
是在编译时确定的,并且instanceIntermediate
的编译时类型是对象
,因此GenerateDataSample
将始终尝试为属性创建类型为System.object
的对象。不要将GenerateDataSample
设为泛型
此外,您实际上不需要向GenerateDataSample
传递实例,只需要传递类型即可
private static object GenerateDataSample(Type typeToWork)
{
object tipoInstance = Activator.CreateInstance(typeToWork);
foreach (PropertyInfo classProperty in typeToWork.GetProperties()) {
object propertyVal;
if (classProperty.PropertyType == typeof(string)) {
propertyVal = RandomString(10, false);
} else {
propertyVal = GenerateDataSample(classProperty.PropertyType);
}
classProperty.SetValue(tipoInstance, propertyVal);
}
return tipoInstance;
}
您还可以创建重载的通用版本:
private static T GenerateDataSample<T>()
{
return (T)GenerateDataSample(typeof(T));
}
private static T GenerateDataSample()
{
返回(T)生成的数据样本(类型(T));
}
然后,您可以使用以下工具创建示例数据:
Destinatary destinataryTest = GenerateDataSample<Destinatary>();
Destinatary destinataryTest=GenerateDataSample();
不客气。另外,由于您是StackOverflow的新手,我想通知您,您可以投票选出好的答案,并接受对您有帮助的答案