-3

I need to deserialize classes created on different machines.

The programs are very similar but have differences in Program name, as well as .Net version etc.

This code below works quite well, except for when I have a Queue in my class. I am unable to search the exsting assemblies to find something suitable.

      public override Type BindToType(string assemblyName, string typeName)
        {
            string typeSearchString;// = typeName.Split('+')[1];

            try
            {
                typeSearchString = typeName.Split('+')[1];
            }
            catch
            {
                var parts = typeName.Split(new string[] { "[[" }, StringSplitOptions.RemoveEmptyEntries)[1].Split(',');
                typeSearchString = @"System.Collections.Generic.Queue"; //This does NOT find Queue<Double> but it does find something else which gives an error
            }

            Type tyType = null;
            string sShortAssemblyName = assemblyName.Split(',')[0];

            System.Reflection.Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();

            foreach (System.Reflection.Assembly ayAssembly in ayAssemblies)
            {
                foreach (Type type in ayAssembly.GetTypes())
                {
                    if (type.FullName.Contains(typeSearchString))
                    {
                        tyType = ayAssembly.GetType(type.FullName);
                        return tyType; 
                    }
                }

            }
            return tyType;
        }

EDIT 1

This is what I have to create a search from:

typeName = "System.Collections.Generic.Queue`1[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
ManInMoon
  • 6,795
  • 15
  • 70
  • 133
  • 3
    If you have the assembly in memory, isn't `typeof(Queue)` working for you? Why do you need to find it using reflection, what are we missing? – Lasse V. Karlsen Oct 07 '19 at 13:08
  • See EDIT 1. This string is all the information I have, I am NOT hard coding this in real life - just to give an example here – ManInMoon Oct 07 '19 at 13:12
  • 3
    @ManInMoon This appears to be an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). The question in its current state is also incomplete and therefore unclear. Read [ask] and then edit the question to provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) that can be used to reproduce the problem, allowing a better understanding of what is being asked. – Nkosi Oct 07 '19 at 13:13
  • Why in the devil's name are you implementing your own serialization? Isn't there one that fit your requirements of the hundreds available? – Euphoric Oct 07 '19 at 13:14
  • The standard serialization works perfectly - EXCEPT across different machines... – ManInMoon Oct 07 '19 at 13:15
  • 2
    There is no `Queue` type in any assembly; there is only `Queue` (CLR name ``Queue`1``, for one generic parameter). It can be obtained from an arbitrary `Queue` by calling `.GetGenericTypeDefinition()`. If you only have a name, things get hairier with parsing (as you've discovered). A concrete `Queue` won't exist until it's instantiated -- that, too, can be done at runtime (with `.MakeGenericType()`), but it's not clear that's what you need here. – Jeroen Mostert Oct 07 '19 at 13:17
  • "EXCEPT across different machines" But that is incorrect! What kind of serialization are you trying to do here? – Euphoric Oct 07 '19 at 13:22
  • @JeroenMostert He should be able to find it if his actual code is doing the same thing the code in the question is doing, by searching for a class where the full name *contains* System.Collections.Generic.Queue, since the generic class would actually contain that name. – Lasse V. Karlsen Oct 07 '19 at 13:49

1 Answers1

0

My own classes appear to have a typeName that contains a "+", for example:

"MyNameSpace.MyDocName+MyClass"

I have been able to use this to determine where to look for the type:

      public override Type BindToType(string assemblyName, string typeName)
        {

            Type tyType = null;
            string sShortAssemblyName = assemblyName.Split(',')[0];

            System.Reflection.Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            string typeSearchString;

            try
            {
                typeSearchString = typeName.Split('+')[1];

                foreach (System.Reflection.Assembly ayAssembly in ayAssemblies)
                {
                    foreach (Type type in ayAssembly.GetTypes())
                    {
                        if (type.FullName.Contains(typeSearchString))
                        {
                            tyType = ayAssembly.GetType(type.FullName);
                            return tyType;
                        }
                    }

                }
            }
            catch
            {
                foreach (System.Reflection.Assembly ayAssembly in ayAssemblies)
                {
                    if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0])
                    {
                        tyType = ayAssembly.GetType(typeName);
                        return tyType;
                    }
                }
            }

            return tyType;
        }

I have posted this answer in case someone else is having similar problems.

ManInMoon
  • 6,795
  • 15
  • 70
  • 133