简体   繁体   中英

What has changed with AppDomain.CurrentDomain.GetAssemblies().SelectMany()?

After migrating my project from VS 2013 to VS 2015 - I am faced with a few object reference errors.

I will identify the problem alongwith an example.

I have two classes, with the same name StatusList - they are under different namespaces.

namespace TestNS.Interop.Cache.CacheItems
{
    public class StatusList
    {
        public string Message { get; set; }
        public StatusList()
        {
            Message = "I am a cache statuslist";
        }
    }
}

namespace TestNS.Interop.Enquiry
{
    public class StatusList
    {
        public string Message { get; set; }
        public StatusList()
        {
            Message = "I am an enquiry statuslist";
        }
    }   
}   

The main program makes a call to AppDomain.CurrentDomain.GetAssemblies() and looks for the first StatusList .

var manyitems = AppDomain.CurrentDomain.GetAssemblies().SelectMany(o => o.GetTypes());
var typeServerCacheItem = manyitems.FirstOrDefault(o => o.Name == name);


class Program
{
    static void Main(string[] args)
    {
        PrintMessagefromAssembly();
    }


    private static void PrintMessagefromAssembly()
    {
        const string name = "StatusList";

        var manyitems = AppDomain.CurrentDomain.GetAssemblies().SelectMany(o => o.GetTypes());
        var typeServerCacheItem = manyitems.FirstOrDefault(o => o.Name == name);

        if (typeServerCacheItem == null)
        {
            Console.WriteLine("No item found");
            return;
        }

        Console.WriteLine(typeServerCacheItem.FullName);
        Console.ReadKey();

    }
}

If you perform a clean and build for this project using VS2013 the type ServerCacheItem returned is the class under CacheItems .

If you perform a clean and build using VS 2015 the type ServerCacheItem returned is the class under Enquiry .

I do realize that the code should be fixed, there is a logical error in the code - a filter criteria should exist for CacheItem s. However I am trying to understand what changed with the way AppDomain.CurrentDomain.GetAssemblies() works?

断点和顺序VS 2015

Watch window VS 2015

断点和顺序VS 2013

Watch window VS 2013

As filter you only specify ShortName of your type: "StatusList" , but also you should specify namespace ie FullName . FirstOrDefault() not guarantee that you will take exactly desired type versus another one. You must not hope that you will get exactly wanted type at this case.

    var typeServerCacheItem = manyitems
.FirstOrDefault(o => o.Name == name && o.Namespace == namespace);

About changes at VS2015, yes, may be they happened, but they must not guarantee you order of resulting set, you should take it on your own

You have made assumptions about the ordering of the objects returned by GetTypes, but this is not defined in the MSDN documentation. This means that there is no guarantee that the first item will always be the same. You need to order the array first (eg, on the namespace) before getting the first item.

要回答这个问题,正确的方法是为缓存项过滤程序集。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM