gpt4 book ai didi

c# - 在没有构造函数的情况下通过反射完全实例化一个对象

转载 作者:行者123 更新时间:2023-11-30 22:21:15 26 4
gpt4 key购买 nike

我找到的与此问题相关的最接近的答案并没有真正帮助解决它,尽管也许我在搜索它时做得不好。

Get a new object instance from a Type

Reflection instantiation

Instantiate an object with a runtime-determined type

现在,我要解决的问题是:

我想完全完整地填充并初始化一个对象,其中我只有类型,而这个对象没有构造函数,直到运行时我才知道它是什么类型。

private readonly Dictionary<string, object> exampleDict = new Dictionary<string, string> { { "String", "\"String\"" }, { "Guid", Guid.NewGuid() }, { "Boolean", False }, { "int", 0 }, { "Decimal", 5.004 }, { "Int32", 0 }, { "Float", 10.01 }, { "Double", 0.101 } };
//Essentially a dictionary of what to init properties to
private object PopulateType(Type propertyType)
{
object o = Activator.CreateInstance(propertyType);
if(exampleDict.hasKey(propertyType.ToString())) //If it is in the dictionary, init it
o = exampleDict[propertyType.Name];
else
foreach(var property in o.getProperties())//Otherwise look at each of its properties and init them to init the object
PopulateType(typeof(property));
}

以上不是我实际拥有的,我怀疑它是否开箱即用(实际代码目前有很多不同的东西,我从 SO 答案中尝试过,而且重写它更容易想要它)

我还需要担心数组(以及扩展列表和字典)的行为会有所不同,但我主要是想把问题的主要部分弄下来。

提前感谢所有帮助 - 我只是希望这是可能的:)

编辑更多细节:换句话说,假设我有以下类(class):

public class ClassOne
{
public string BirthCountry {get; set;}
public string BirthCity {get; set;}
}
public class ClassTwo
{
public string FirstName {get; set;}
public string LastName {get; set;}
public ClassOne BirthPlace {get; set;}
}

我想做的是调用:

object newObject = PopulateType(typeof(ClassOne))

object newObject = PopulateType(typeof(ClassTwo))

我事先不知道我会使用哪一个,也没有构造函数。我希望能够将 BirthCountryBirthCity 设置为“String”,如果它是 ClassOne 放入 PopulateType ,我希望能够设置 FirstName="String"LastName="String"BirthPlace=new ClassOne { BirthCountry="String", BirthCity ="字符串"}但我希望能够为我碰巧拥有的任何类(class)执行此操作(这些只是示例)。

进一步编辑

我能够从类型中创建基类。但是我无法点击属性将它们设置为 null 以外的任何值。

编辑 - 在 Fruity Geek(非常感谢 friend )的帮助下,我能够让程序运行。

private object PopulateType(Type propertyType)
{
object o = null;
if (exampleDict.ContainsKey(propertyType.Name))
o = exampleDict[propertyType.Name];
else
{
var types = AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(s => s.GetTypes()).Where(p => propertyType.IsAssignableFrom(p));
try{o = Activator.CreateInstance(propertyType);}
catch{o = Activator.CreateInstance(types.Last());}
foreach (PropertyInfo prop in o.GetType().GetProperties())
try
{
prop.SetValue(o, PopulateType(prop.PropertyType), null);
}
catch (Exception){}
}
return o;
}

请注意,try/catch 是为了:如果接口(interface)未实现,则防止爆炸,并且不要尝试实例化字典/列表/数组(那些仍然需要工作)

最佳答案

您可以使用反射来检查属性是否存在并设置它。

PopulateType(Object obj)
{
//A dictionary of values to set for found properties
Dictionary<String, Object> defaultValues = new Dictionary<String, Object>();
defaultValues.Add("BirthPlace", "Amercia");
for (var defaultValue in defaultValues)
{
//Here is an example that just set BirthPlace to a known value Amercia
PropertyInfo prop = obj.GetType().GetProperty(defaultValue.Key, BindingFlags.Public | BindingFlags.Instance);
if(null != prop && prop.CanWrite)
{
prop.SetValue(obj, defaultValue.Value, null);
}
}
}

关于c# - 在没有构造函数的情况下通过反射完全实例化一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14492798/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com