Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 优化构造函数调用_C#_.net - Fatal编程技术网

C# 优化构造函数调用

C# 优化构造函数调用,c#,.net,C#,.net,我正在使用以下方法创建类的原始实例: FormatterServices.GetUninitializedObject 稍后,我填充实例的数据,并使用以下命令执行无参数构造函数: paremeterlessCtor.Invoke(instance, null); 我只是调用无参数构造函数,让用户控制对象的初始化过程。但是这两个函数的问题是昂贵的(是的,我超时了)。我以前有一个优化版本,但是如果用户不能控制对象的初始化并缓存委托,而不是直接调用Invoke(避免反射),那么我需要调用构造函数,

我正在使用以下方法创建类的原始实例:

FormatterServices.GetUninitializedObject
稍后,我填充实例的数据,并使用以下命令执行无参数构造函数:

paremeterlessCtor.Invoke(instance, null);
我只是调用无参数构造函数,让用户控制对象的初始化过程。但是这两个函数的问题是昂贵的(是的,我超时了)。我以前有一个优化版本,但是如果用户不能控制对象的初始化并缓存委托,而不是直接调用Invoke(避免反射),那么我需要调用构造函数,它是
constructorinfo
类型,而不是
MethodInfo
,所以我不能用它来做一个委托,也不能做一个
预编译表达式
。那么如何避免使用调用重载来调用构造函数呢

还有什么方法比
GetUninitializedObject
更有效吗

谢谢

EDIT:原始实例是在运行时为ORM库解析的类型,我不需要它,但我喜欢重新设计轮子并完成所有操作,但我只想优化Invoke-ctor以避免反射(如果可能)。我知道我可以为此创建initilize方法,但我觉得当映射完成时,构造函数在语义上更适合用户的初始化过程

如果需要了解我需要优化的内容,请提供一些格式化的代码:

private static List<DerivedType> internal_getAllRows<DerivedType>(SelectorMode mode) where DerivedType : TemplateInstance
{
//Create a raw instance of the generic type to be mapped
instance = (DerivedType)FormatterServices.GetUninitializedObject(typeof(DerivedType));
//Fill the raw instance with relational data
instance.initializeRaw();
instance.initialize(typeof(DerivedType));
//Get the parameterless constructor
var ctor = typeof(DerivedType).GetConstructor(Types.EmptyTypes)
ctor.Invoke(instance, null); //Invoke the constructor on the mapped instance, I am trying to avoid reflection HERE !
}
私有静态列表内部\u getAllRows(SelectorMode模式),其中DerivedType:TemplateInstance
{
//创建要映射的泛型类型的原始实例
实例=(DerivedType)FormatterServices.GetUninitializedObject(typeof(DerivedType));
//用关系数据填充原始实例
instance.initializeRaw();
初始化(typeof(DerivedType));
//获取无参数构造函数
var ctor=typeof(DerivedType).GetConstructor(Types.EmptyTypes)
Invoke(instance,null);//调用映射实例上的构造函数,我在这里试图避免反射!
}

我曾经创建过这个方法来创建构造函数的委托。这不是一个100%的解决方案,但它可能会给你一个开始。今天晚些时候我会编辑这个答案

*编辑*

最后,它起作用了(在op de op的帮助下!):

公共静态操作CreateDelegate(此构造函数信息构造函数)
T:在哪里上课
{
if(构造函数==null)
抛出新的ArgumentNullException(“构造函数”);
//创建动态方法
DynamicMethod=新的DynamicMethod(
constructor.DeclaringType.Name+“”+Guid.NewGuid().ToString().Replace(“-”,”),
类型(无效),
新[]{typeof(T)},
构造函数。模块,
正确的);
//创建il
ILGenerator ILGenerator=方法.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);//将引用复制到堆栈上的实例。
ilGenerator.Emit(OpCodes.Call,构造函数);//调用构造函数。
ilGenerator.Emit(操作码.Ret);
//返回委托:)
return(Action)方法.CreateDelegate(typeof(Action));
}

为什么不简单地实现一个公开
初始化
方法的接口呢?在初始化构造函数之后调用它似乎已经是一种非常糟糕的做法(事实上,现在不是调用了两次吗)?投票关闭,因为我们需要看到更多的代码来分析当前代码在做什么。这适用于ORM,在ORM中,默认构造函数要么由具有定义状态(比如映射)的库调用,要么由处于“创建新”状态的用户调用。因此,每当库从DB映射时,用户需要控制,我不知道是否有比构造函数更合适的东西。。。但这并不是我想改变我的方法的问题,我只是想知道如何避免调用过载引起的反射。这个问题深入到了反射中。对于投票赞成关闭它的人来说:这是一个有效的问题,对我来说,这是一个明确的问题。但我明白这并不清楚,因为他们不了解深层次的问题。当你不知道如何理解某个问题时,请不要关闭该问题,也不要否决该问题。这将创建一个新实例,而我已经拥有一个填充了数据的实例,我只需要调用构造函数而不创建新实例,因为构造函数并不是真正创建实例(只有CLR.new)它应该是有效的,这要感谢这个重载:但是我不能应用一些缓存优化,比如预编译表达式或委托,因为构造函数是ConstructorInfo类型而不是MethodInfo。你唯一的论点是,对于另一个开发人员来说,在构造函数中编写逻辑更方便?这看起来很麻烦。这是一个很好的开始。。。我将在今天晚些时候测试这方面的性能,但我认为缓存委托总是比reflection.True更快。委托调用总是比反射调用快。您应该创建一次委托,存储它,并根据需要使用它。我原来的方法有一个内部缓存机制。我从代码中删除了这个,因为它不属于您的问题,因为存储结果也可以在其他地方进行。@MartinMulder,
newobj
是否创建新实例?OP希望在现有实例上调用ctor。我一直试图在IL中实现这一点,但到目前为止还没有成功。您的新代码也不起作用,它抛出了一个VerificationException(操作可能会破坏运行时的稳定性)。我也试过了,但我似乎无法让它起作用。@ThomasLevesque:我知道。。。因此我说“仍然不起作用”。)
public static Action<T> CreateDelegate<T>(this ConstructorInfo constructor)
    where T: class
{
    if (constructor == null)
        throw new ArgumentNullException("constructor");

    // Create the dynamic method
    DynamicMethod method = new DynamicMethod(
        constructor.DeclaringType.Name + "_" + Guid.NewGuid().ToString().Replace("-", ""),
        typeof(void),
        new[] { typeof(T) },
        constructor.Module,
        true);


    // Create the il
    ILGenerator ilGenerator = method.GetILGenerator();
    ilGenerator.Emit(OpCodes.Ldarg_0); // Copy the reference to the instance on the stack.
    ilGenerator.Emit(OpCodes.Call, constructor); // Call the constructor.
    ilGenerator.Emit(OpCodes.Ret); 

    // Return the delegate :)
    return (Action<T>)method.CreateDelegate(typeof(Action<T>));
}