C# 使用IL Emit替换Activator.CreateInstance

C# 使用IL Emit替换Activator.CreateInstance,c#,performance,reflection,instantiation,reflection.emit,C#,Performance,Reflection,Instantiation,Reflection.emit,我有一个实现接口的类,接口有一个多参数构造函数和一个静态排序集合。此类是具有许多继承类的基类 internal class SCO : IVotable { public SCO(SPListItem item, List<Vote> votes) { //Initialize Object } public static List<T> SortedCollection<T>(SPListItemCollec

我有一个实现接口的类,接口有一个多参数构造函数和一个静态排序集合。此类是具有许多继承类的基类

internal class SCO : IVotable
{
    public SCO(SPListItem item, List<Vote> votes)
    {
        //Initialize Object
    }

    public static List<T> SortedCollection<T>(SPListItemCollection items, ListSortType sortType, List<Vote> votes) where T : IVotable
    {
        var returnlist = new List<T>();
        Type genericType = typeof(T);
        for (int i = 0; i < items.Count; i++) { returnlist.Add((T)Activator.CreateInstance(genericType, new object[] { items[i], votes })); }
        switch (sortType)
        {
            case ListSortType.Hot:
                returnlist.Sort((p1, p2) => p2.HotScore.CompareTo(p1.HotScore));
                break;
            case ListSortType.Top:
                returnlist.Sort((p1, p2) => p2.VoteTotal.CompareTo(p1.VoteTotal));
                break;
            case ListSortType.Recent:
                returnlist.Sort((p1, p2) => p2.CreatedDate.CompareTo(p1.CreatedDate));
                break;
        }
        return returnlist;
    }
}
参考博客:

我有一个新的Activator替代品,它使用托管在CodePlex上的IL生成。您还可以通过Nuget(单个源文件,不包含程序集)获取它

FasterActivator的源代码为

用法如下所述

private static readonly Dictionary<Type, DynamicCreationDelegate> _cachedCreationDelegates = new Dictionary<Type, DynamicCreationDelegate>();

private static DynamicCreationDelegate CreateOrGet(Type typeToCreate)
{
    DynamicCreationDelegate result = null;

    if (!_cachedCreationDelegates.TryGetValue(typeToCreate, out result))
    {
        result = FastActivator.GenerateDelegate(typeToCreate, 
        /* List of types that make up the constructor signature of the type being constructed */
        typeof(SPListItem), typeof(List<Vote>));
        _cachedCreationDelegates.Add(result);
    }

    return result;
}

// Usage 
for (int i = 0; i < items.Count; i++) 
{ 
    var creationDelegate = CreateOrGet(typeof(genericType));
    returnlist.Add((T)creationDelegate(new object[] { items[i], votes })); 
}
private static readonly Dictionary\u cachedcreationelegates=new Dictionary();
专用静态动态CreationElegate CreateOrGet(键入typeToCreate)
{
DynamicCreationLegate结果=空;
if(!\u cachedCreationElegates.TryGetValue(typeToCreate,out结果))
{
结果=FastActivator.GenerateDelegate(typeToCreate,
/*构成所构造类型的构造函数签名的类型列表*/
typeof(SPListItem),typeof(List));
_CachedCreationElegates.Add(结果);
}
返回结果;
}
//用法
对于(int i=0;i
哦,这是一个通用版本,应该更快

private static readonly Func<SPListItem, List<T>, T> _creationFunc;
private static Func<SPListItem, List<T>, T> CreateOrGetFunc()
{
    if (!_creationFunc == null)
        _creationFunc = FastActivator.GenerateFunc<Func<SPListItem, List<T>, T>>(/* IL generator knows all type info from generic params now */);

    return _creationFunc;
}

// Usage
for (int i = 0; i < items.Count; i++) 
{ 
    var creationFunc = CreateOrGetFunc();
    returnlist.Add(creationFunc(items[i], votes )); 
}
private static readonly Func\u creationFunc;
私有静态函数CreateOrGetFunc()
{
如果(!\u creationFunc==null)
_creationFunc=FastActivator.GenerateFunc(/*IL生成器现在知道泛型参数中的所有类型信息*/);
返回_creationFunc;
}
//用法
对于(int i=0;i

希望这有帮助

我有一个使用托管在CodePlex上的IL生成的Activator的替代品。您还可以通过Nuget(单个源文件,不包含程序集)获取它

FasterActivator的源代码为

用法如下所述

private static readonly Dictionary<Type, DynamicCreationDelegate> _cachedCreationDelegates = new Dictionary<Type, DynamicCreationDelegate>();

private static DynamicCreationDelegate CreateOrGet(Type typeToCreate)
{
    DynamicCreationDelegate result = null;

    if (!_cachedCreationDelegates.TryGetValue(typeToCreate, out result))
    {
        result = FastActivator.GenerateDelegate(typeToCreate, 
        /* List of types that make up the constructor signature of the type being constructed */
        typeof(SPListItem), typeof(List<Vote>));
        _cachedCreationDelegates.Add(result);
    }

    return result;
}

// Usage 
for (int i = 0; i < items.Count; i++) 
{ 
    var creationDelegate = CreateOrGet(typeof(genericType));
    returnlist.Add((T)creationDelegate(new object[] { items[i], votes })); 
}
private static readonly Dictionary\u cachedcreationelegates=new Dictionary();
专用静态动态CreationElegate CreateOrGet(键入typeToCreate)
{
DynamicCreationLegate结果=空;
if(!\u cachedCreationElegates.TryGetValue(typeToCreate,out结果))
{
结果=FastActivator.GenerateDelegate(typeToCreate,
/*构成所构造类型的构造函数签名的类型列表*/
typeof(SPListItem),typeof(List));
_CachedCreationElegates.Add(结果);
}
返回结果;
}
//用法
对于(int i=0;i
哦,这是一个通用版本,应该更快

private static readonly Func<SPListItem, List<T>, T> _creationFunc;
private static Func<SPListItem, List<T>, T> CreateOrGetFunc()
{
    if (!_creationFunc == null)
        _creationFunc = FastActivator.GenerateFunc<Func<SPListItem, List<T>, T>>(/* IL generator knows all type info from generic params now */);

    return _creationFunc;
}

// Usage
for (int i = 0; i < items.Count; i++) 
{ 
    var creationFunc = CreateOrGetFunc();
    returnlist.Add(creationFunc(items[i], votes )); 
}
private static readonly Func\u creationFunc;
私有静态函数CreateOrGetFunc()
{
如果(!\u creationFunc==null)
_creationFunc=FastActivator.GenerateFunc(/*IL生成器现在知道泛型参数中的所有类型信息*/);
返回_creationFunc;
}
//用法
对于(int i=0;i

希望这有帮助

我知道你有答案了。帮助器类调用IL构造函数(我以前应该这样做,但缺少一个很好的理由):

用法如下:

// suppose you want to call the constructor for this class  
// but generalizing the return to ISomeInterface
public class AClass : ISomeInterface
{
   public class(int intParam, String stringParam) { }
}

// construct the factory method Func<int, string, ISomeInterface>
var createAClassInstance = ReflectionHelper
   // return type + constructor params
   .CreateFactoryMethod<ISomeInterface, int, string>(typeof(AClass));

var instance = createAClassInstance(10, "hello constructor");
//假设要调用此类的构造函数
//但概括地说,这是对界面的回归
公共类AClass:接口
{
公共类(int intParam,String stringParam){}
}
//构造工厂方法Func
var createAclasInstance=ReflectionHelper
//返回类型+构造函数参数
.CreateFactoryMethod(typeof(AClass));
var instance=createaclasinstance(10,“hello构造函数”);

我知道你有答案了。帮助器类调用IL构造函数(我以前应该这样做,但缺少一个很好的理由):

用法如下:

// suppose you want to call the constructor for this class  
// but generalizing the return to ISomeInterface
public class AClass : ISomeInterface
{
   public class(int intParam, String stringParam) { }
}

// construct the factory method Func<int, string, ISomeInterface>
var createAClassInstance = ReflectionHelper
   // return type + constructor params
   .CreateFactoryMethod<ISomeInterface, int, string>(typeof(AClass));

var instance = createAClassInstance(10, "hello constructor");
//假设要调用此类的构造函数
//但概括地说,这是对界面的回归
公共类AClass:接口
{
公共类(int intParam,String stringParam){}
}
//构造工厂方法Func
var createAclasInstance=ReflectionHelper
//返回类型+构造函数参数
.CreateFactoryMethod(typeof(AClass));
var instance=createaclasinstance(10,“hello构造函数”);

如果您愿意接受一些重复,那么您可以使用委托,而不是处理IL(正如您发现的那样,IL可能会很快变得复杂)。比如:

internal class SCO : IVotable
{
    protected static List<T> SortedCollection<T>
        (SPListItemCollection items, ListSortType sortType, List<Vote> votes,
        Func<SPListItem, List<Vote>, T> factory) where T : IVotable
    {
        var returnlist = new List<T>();
        Type genericType = typeof(T);
        for (int i = 0; i < items.Count; i++)
            returnlist.Add(factory(items[i], votes));

        // etc.
    }
}

class ChildClass : SCO
{
    public static List<ChildClass> SortedCollection
        (SPListItemCollection items, ListSortType sortType, List<Vote> votes)
    {
        return SCO.SortedCollection<ChildClass>(
            items, sortType, votes, (i, vs) => new ChildClass(i, vs));
    }
}
内部类SCO:IVotable
{
受保护的静态列表分类集合
(SPListItemCollection items、ListSortType、sortType、列表投票、,
Func工厂)其中T:IVotable
{
var returnlist=新列表();
类型genericType=typeof(T);
对于(int i=0;i新的子类(i,vs));
}
}

这样做应该非常快,甚至可能比使用IL-emit时快一点。

如果您愿意接受一些重复,那么您可以使用代理,而不是处理IL(正如您发现的那样,IL可能会很快变得复杂)。比如:

internal class SCO : IVotable
{
    protected static List<T> SortedCollection<T>
        (SPListItemCollection items, ListSortType sortType, List<Vote> votes,
        Func<SPListItem, List<Vote>, T> factory) where T : IVotable
    {
        var returnlist = new List<T>();
        Type genericType = typeof(T);
        for (int i = 0; i < items.Count; i++)
            returnlist.Add(factory(items[i], votes));

        // etc.
    }
}

class ChildClass : SCO
{
    public static List<ChildClass> SortedCollection
        (SPListItemCollection items, ListSortType sortType, List<Vote> votes)
    {
        return SCO.SortedCollection<ChildClass>(
            items, sortType, votes, (i, vs) => new ChildClass(i, vs));
    }
}
内部类SCO:IVotable
{
受保护的静态列表分类集合
(SPListItemCollection items、ListSortType、sortType、列表投票、,
Func工厂)其中T:IVotable
{
var returnlist=新列表();
类型genericType=typeof