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的新手,我想通知您,您可以投票选出好的答案,并接受对您有帮助的答案