Using FastActivator in place of Activator.CreateIn

2019-08-20 03:00发布

问题:

Trying to use Class shown here as a sample for Activator.CreateInstance() http://codeblocks.codeplex.com/wikipage?title=FasterActivator%20Sample

    public static List<T> SortedCollection<T>(SPListItemCollection items, ListSortType sortType, List<Vote> votes) where T : IVotable
    {
        var returnlist = new List<T>();
        var functionCreator = FastActivator.GenerateFunc<Func<SPListItem, List<Vote>, T>>();

        for (int i = 0; i < items.Count; i++) { returnlist.Add(functionCreator(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;
    }

Error is in the for loop, getting MethodAccessException:

.Post__041c49eec0a6466da11894b0455b1162(Microsoft.SharePoint.SPListItem, System.Collections.Generic.List1)`

Console App with Error (requires FastActivator class to be in the same namespace):

namespace testcase
{
    class Program
    {
        static void Main(string[] args)
        {
            var vote1 = new Vote() {ItemID=1};
            List<Vote> votes = new List<Vote>();
            votes.Add(vote1);

            List<string> strings = new List<string>();
            strings.Add("test");
            List<Post> posts = Post.SortedCollection<Post>(strings, ListSortType.Hot, votes);
        }
    }

    internal interface IVotable
    {
        double HotScore { get; set; }
        double VoteTotal { get; set; }
        DateTime CreatedDate { get; set; }
    }
    internal class SCO : IVotable
    {
        public double HotScore { get; set; }
        public double VoteTotal { get; set; }
        public DateTime CreatedDate { get; set; }

        public SCO(string item, List<Vote> votes)
        {
            VoteTotal = 10;
            HotScore = 10;
            CreatedDate = DateTime.Now;
        }

        public static List<T> SortedCollection<T>(List<string> items, ListSortType sortType, List<Vote> votes) where T : IVotable
        {
            var returnlist = new List<T>();
            Type genericType = typeof(T);
            var functionCreator = FastActivator.GenerateFunc<Func<string, List<Vote>, T>>();

            for (int i = 0; i < items.Count; i++) { returnlist.Add(functionCreator(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;
        }
    }

    class Vote
    {
        public double ItemID { get; set; }
    }
    class VoteMeta
    {
        public double UpVotes { get; set; }
        public double DownVotes { get; set; }
        public string CurrentUserVoteClass { get; set; }
    }
    internal enum ListSortType { Hot, Top, Recent };

    class Post : SCO
    {
        public string Summary { get; set; }
        public Uri Link { get; set; }

        public Post(string item, List<Vote> votes)
            : base(item, votes)
        {
            Summary = "Summary";
            Link = new UriBuilder("http://www.google.com").Uri;
        }
    }
}

回答1:

You probably have a non-public constructor somewhere. Not explicitly specifying a visibility on a namespace member makes it internal, not public. These modifications made your example program work correctly. Note that the dynamic method is in a dynamically generated assembly and as such doesn't have access to internal members.