C# 我们可以实例化一个刚声明并传递给另一个类中方法的类的对象吗
我正在实现一个自动映射器,并被困在这种情况下:C# 我们可以实例化一个刚声明并传递给另一个类中方法的类的对象吗,c#,C#,我正在实现一个自动映射器,并被困在这种情况下: classsource的对象中有classcommon的对象,该对象刚刚声明,但没有实例化 当我将classsource的对象传递给program类的方法映射时 如何获取内部对象(公共类对象)的类型并实例化它 public class common { public int x; } public class source { public common obj; } class program { static voi
source
的对象中有classcommon
的对象,该对象刚刚声明,但没有实例化source
的对象传递给program
类的方法映射时public class common
{
public int x;
}
public class source
{
public common obj;
}
class program
{
static void main()
{
source obj = new source();
map(obj);
}
void map(source obj)
{
**how can i get type of inner object class and instantiate it**
}
}
我使用了Type.GetType(),但给出的是空的。所以映射方法的工作实现:
common map(source obj)
{
var typeOfObj = obj.GetType().GetFields(
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance)
.First(fi=>fi.Name == "obj");
return (common) Activator.CreateInstance(typeOfObj.FieldType);
}
已存档
如果您需要为obj.obj
获取类型,则可以使用:
void map(source obj){
obj.obj.GetType() ...
}
但由于您尚未实例化它,因此需要进行反射:
var f = typeof(source).GetField("obj");
f.FieldType // contains expected
void map(source obj)
{
obj.obj = new common();
}
如果私有字段是一个问题,那么您必须通过以下方法对所有字段数组进行迭代:
FieldInfo[] fields = source.GetFields(
BindingFlags.NonPublic |
BindingFlags.Instance);
并定位名为“obj”的字段以便映射方法的工作实现:
common map(source obj)
{
var typeOfObj = obj.GetType().GetFields(
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance)
.First(fi=>fi.Name == "obj");
return (common) Activator.CreateInstance(typeOfObj.FieldType);
}
已存档
如果您需要为obj.obj
获取类型,则可以使用:
void map(source obj){
obj.obj.GetType() ...
}
但由于您尚未实例化它,因此需要进行反射:
var f = typeof(source).GetField("obj");
f.FieldType // contains expected
void map(source obj)
{
obj.obj = new common();
}
如果私有字段是一个问题,那么您必须通过以下方法对所有字段数组进行迭代:
FieldInfo[] fields = source.GetFields(
BindingFlags.NonPublic |
BindingFlags.Instance);
并找到名为“obj”的字段,如果要实例化收到的类,可以使用Activator:
Activator.CreateInstance(obj.obj.GetType());
虽然我不确定你想达到什么目的 如果要实例化收到的类,可以使用Activator:
Activator.CreateInstance(obj.obj.GetType());
虽然我不确定你想达到什么目的 这方面的问题在哪里?无需反思:
var f = typeof(source).GetField("obj");
f.FieldType // contains expected
void map(source obj)
{
obj.obj = new common();
}
基本上,您可以根据需要修改任何传递的对象,方法中唯一不能做的就是将
obj
设置为source
的一个新实例,您需要使用ref
-关键字。在您的例子中,您知道传递对象的类型,因此我猜您也知道相关类由什么组成,从而知道obj
-属性的类型 这方面的问题在哪里?无需反思:
var f = typeof(source).GetField("obj");
f.FieldType // contains expected
void map(source obj)
{
obj.obj = new common();
}
基本上,您可以根据需要修改任何传递的对象,方法中唯一不能做的就是将
obj
设置为source
的一个新实例,您需要使用ref
-关键字。在您的例子中,您知道传递对象的类型,因此我猜您也知道相关类由什么组成,从而知道obj
-属性的类型 如果我错了,请纠正我的理解
一旦实例化了源
对象,就需要实例化内部的公共
对象。如果是这样,您可以在源代码
中编写一个构造函数
,它将实例化您的私有公共对象。像这样的
class source
{
common obj;
public source()
{
obj = new common();
}
}
如果我错了,请纠正我的理解
一旦实例化了源
对象,就需要实例化内部的公共
对象。如果是这样,您可以在源代码
中编写一个构造函数
,它将实例化您的私有公共对象。像这样的
class source
{
common obj;
public source()
{
obj = new common();
}
}
从输入对象获取类型字段信息,然后实例化该字段类型的对象,并将值设置回输入对象:
// Get field info for source.obj
FieldInfo fieldInfo = obj.GetType().GetField("obj", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
// Instantiate object without initializing it
object instance = FormatterServices.GetUninitializedObject(fieldInfo.FieldType);
// set instantiated object reference to the field source.obj
fieldInfo.SetValue(obj, instance);
如果您正在制作“AutoMapper”,那么它将满足您的需要,因为它不使用构造函数,而在其他答案中,构造函数应该是默认的(无参数的)构造函数
您可以在没有默认(无参数)构造函数的情况下比较实例化对象的不同方法
递归映射的完整代码示例:
public static void Main()
{
_genericMapInfo = typeof(Program).GetMethod("map", BindingFlags.NonPublic | BindingFlags.Static);
Test t = null;
map(ref t);
Console.WriteLine(t == null); // False
Console.WriteLine(t.A); // Hello World!
Console.WriteLine(t.B.A); // 1337
Console.WriteLine(t.B.B); // Hello World!
}
static MethodInfo _genericMapInfo;
static void map<T>(ref T obj)
where T : class
{
if(obj == null)
obj = (T)FormatterServices.GetUninitializedObject(typeof(T));
foreach(FieldInfo fInfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
Type fieldType = fInfo.FieldType;
TypeCode tCode = Type.GetTypeCode(fInfo.FieldType);
if(tCode == TypeCode.Object)
{
object[] param = new object[] { fInfo.GetValue(obj) };
_genericMapInfo.MakeGenericMethod(fieldType).Invoke(null, param);
fInfo.SetValue(obj, param[0]);
}
else if(tCode == TypeCode.String)
{
fInfo.SetValue(obj, "Hello World!");
}
else if(tCode == TypeCode.Int32)
{
fInfo.SetValue(obj, 1337);
}
}
}
public class Test
{
public string A { get; set; }
public TestInside B { get; private set; }
public Test()
{
A = "no siema";
}
}
public class TestInside
{
public int A { get; private set; }
public string B { get; set; }
public TestInside(int _someInteger)
{
A = _someInteger;
}
}
publicstaticvoidmain()
{
_genericMapInfo=typeof(Program.GetMethod(“map”,BindingFlags.NonPublic | BindingFlags.Static);
测试t=null;
地图(参考t);
Console.WriteLine(t==null);//False
Console.WriteLine(t.A);//你好,世界!
Console.WriteLine(t.B.A);/1337
Console.WriteLine(t.B.B);//你好,世界!
}
静态方法信息_genericMapInfo;
静态空隙图(参考T obj)
T:在哪里上课
{
if(obj==null)
obj=(T)FormatterServices.GetUninitializedObject(typeof(T));
foreach(类型为(T).GetFields的FieldInfo fInfo(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
类型fieldType=fInfo.fieldType;
TypeCode tCode=Type.GetTypeCode(fInfo.FieldType);
if(tCode==TypeCode.Object)
{
object[]param=new object[]{fInfo.GetValue(obj)};
_genericMapInfo.MakeGenericMethod(fieldType).Invoke(null,param);
fInfo.SetValue(对象,参数[0]);
}
else if(tCode==TypeCode.String)
{
SetValue(obj,“你好,世界!”);
}
else if(tCode==TypeCode.Int32)
{
fInfo.SetValue(obj,1337);
}
}
}
公开课考试
{
公共字符串A{get;set;}
公共证明码B{get;私有集;}
公开考试()
{
A=“没有siema”;
}
}
公开课证言
{
public int A{get;private set;}
公共字符串B{get;set;}
公共验证码(int\u someInteger)
{
A=_someInteger;
}
}
从输入对象获取类型字段信息,然后实例化该字段类型的对象,并将值设置回输入对象:
// Get field info for source.obj
FieldInfo fieldInfo = obj.GetType().GetField("obj", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
// Instantiate object without initializing it
object instance = FormatterServices.GetUninitializedObject(fieldInfo.FieldType);
// set instantiated object reference to the field source.obj
fieldInfo.SetValue(obj, instance);
如果您正在制作“AutoMapper”,那么它将满足您的需要,因为它不使用构造函数,而在其他答案中,构造函数应该是默认的(无参数的)构造函数
您可以在没有默认(无参数)构造函数的情况下比较实例化对象的不同方法
递归映射的完整代码示例:
public static void Main()
{
_genericMapInfo = typeof(Program).GetMethod("map", BindingFlags.NonPublic | BindingFlags.Static);
Test t = null;
map(ref t);
Console.WriteLine(t == null); // False
Console.WriteLine(t.A); // Hello World!
Console.WriteLine(t.B.A); // 1337
Console.WriteLine(t.B.B); // Hello World!
}
static MethodInfo _genericMapInfo;
static void map<T>(ref T obj)
where T : class
{
if(obj == null)
obj = (T)FormatterServices.GetUninitializedObject(typeof(T));
foreach(FieldInfo fInfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
Type fieldType = fInfo.FieldType;
TypeCode tCode = Type.GetTypeCode(fInfo.FieldType);
if(tCode == TypeCode.Object)
{
object[] param = new object[] { fInfo.GetValue(obj) };
_genericMapInfo.MakeGenericMethod(fieldType).Invoke(null, param);
fInfo.SetValue(obj, param[0]);
}
else if(tCode == TypeCode.String)
{
fInfo.SetValue(obj, "Hello World!");
}
else if(tCode == TypeCode.Int32)
{
fInfo.SetValue(obj, 1337);
}
}
}
public class Test
{
public string A { get; set; }
public TestInside B { get; private set; }
public Test()
{
A = "no siema";
}
}
public class TestInside
{
public int A { get; private set; }
public string B { get; set; }
public TestInside(int _someInteger)
{
A = _someInteger;
}
}
publicstaticvoidmain()
{
_genericMapInfo=typeof(Program.GetMethod(“map”,BindingFlags.NonPublic | BindingFlags.Static);
测试t=null;
地图(参考t);
Console.WriteLine(t==null);//False
Console.WriteLine(t.A);//你好,世界!
Console.WriteLine(t.B.A);/1337