Answer-ID
  • Întrebări
  • Tag-uri
  • Categorii
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
Brian Sullivan
Brian Sullivan

Pot serializa un obiect C # Type?

Încerc să serializez un obiect Tip în felul următor:

Type myType = typeof (StringBuilder);
var serializer = new XmlSerializer(typeof(Type));
TextWriter writer = new StringWriter();
serializer.Serialize(writer, myType);

Când fac acest lucru, apelul către Serialize aruncă următoarea excepție:

"Tipul System.Text.StringBuilder nu a fost așteptat   Atributul XmlInclude sau SoapInclude pentru a specifica tipurile care nu sunt   cunoscute în mod static. "

Există o modalitate de a serializa obiectul Type ? Rețineți că nu încerc să serializez codul StringBuilder , ci obiectul Type care conține metadatele despre clasa StringBuilder .

50 2008-08-15T14:46:07+00:00 5
Programare
serialization
c#
Comentarii la întrebare (0)
AdamSane
15 august 2008 в 6:50
2008-08-15T18:50:09+00:00
Mai mult
Sursă
Editează
#12314

Doar sa uitat la definiția sa, nu este marcată ca Serializabilă. Dacă aveți într-adevăr nevoie ca aceste date să fie serializate, atunci poate fi necesar să le convertiți într-o clasă personalizată care este marcată ca atare.

public abstract class Type : System.Reflection.MemberInfo
    Member of System

Summary:
Represents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types.

Attributes:
[System.Runtime.InteropServices.ClassInterfaceAttribute(0),
System.Runtime.InteropServices.ComDefaultInterfaceAttribute(System.Runtime.InteropServices._Type),
System.Runtime.InteropServices.ComVisibleAttribute(true)]
0
0
Comentarii (0)
rjzii
15 august 2008 в 6:50
2008-08-15T18:50:59+00:00
Mai mult
Sursă
Editează
#12315

Conform documentației MSDN de tip System.Type [1], ar trebui să puteți serializa obiectul System.Type. Cu toate acestea, deoarece eroarea se referă în mod explicit la System.Text.StringBuilder, este probabil clasa care cauzează eroarea de serializare.

[1] Type Class (System) - http://msdn.microsoft.com/en-us/library/system.type.aspx

0
0
Comentarii (0)
Brian Sullivan
15 august 2008 в 7:12
2008-08-15T19:12:43+00:00
Mai mult
Sursă
Editează
#12342

Nu știam că un obiect Type ar putea fi creat doar cu un șir care conține numele complet calificat. Pentru a obține numele complet calificat, puteți utiliza următoarele:

string typeName = typeof (StringBuilder).FullName;

Puteți persista apoi acest șir oricât de necesar, apoi reconstruiți tipul de genul acesta:

Type t = Type.GetType(typeName);

Dacă aveți nevoie să creați o instanță de tip, puteți face acest lucru:

object o = Activator.CreateInstance(t);

Dacă bifați valoarea o.GetType (), va fi StringBuilder, exact așa cum vă așteptați.

0
0
Comentarii (0)
hypehuman
21 martie 2012 в 9:34
2012-03-21T21:34:43+00:00
Mai mult
Sursă
Editează
#9809872

Am avut aceeași problemă, iar soluția mea era să creez o clasă SerializableType. Se convertește liber la și de la System.Type, dar este serializat ca un șir. Tot ce trebuie să faceți este să declarați variabila ca tip Serializable, și de atunci puteți să o referiți la ea ca System.Type.

Aici este clasa:

// a version of System.Type that can be serialized
[DataContract]
public class SerializableType
{
    public Type type;

   //when serializing, store as a string
    [DataMember]
    string TypeString
    {
        get
        {
            if (type == null)
                return null;
            return type.FullName;
        }
        set
        {
            if (value == null)
                type = null;
            else
            {
                type = Type.GetType(value);
            }
        }
    }

   //constructors
    public SerializableType()
    {
        type = null;
    }
    public SerializableType(Type t)
    {
        type = t;
    }

   //allow SerializableType to implicitly be converted to and from System.Type
    static public implicit operator Type(SerializableType stype)
    {
        return stype.type;
    }
    static public implicit operator SerializableType(Type t)
    {
        return new SerializableType(t);
    }

   //overload the == and != operators
    public static bool operator ==(SerializableType a, SerializableType b)
    {
       //If both are null, or both are same instance, return true.
        if (System.Object.ReferenceEquals(a, b))
        {
            return true;
        }

       //If one is null, but not both, return false.
        if (((object)a == null) || ((object)b == null))
        {
            return false;
        }

       //Return true if the fields match:
        return a.type == b.type;
    }
    public static bool operator !=(SerializableType a, SerializableType b)
    {
        return !(a == b);
    }
   //we don't need to overload operators between SerializableType and System.Type because we already enabled them to implicitly convert

    public override int GetHashCode()
    {
        return type.GetHashCode();
    }

   //overload the .Equals method
    public override bool Equals(System.Object obj)
    {
       //If parameter is null return false.
        if (obj == null)
        {
            return false;
        }

       //If parameter cannot be cast to SerializableType return false.
        SerializableType p = obj as SerializableType;
        if ((System.Object)p == null)
        {
            return false;
        }

       //Return true if the fields match:
        return (type == p.type);
    }
    public bool Equals(SerializableType p)
    {
       //If parameter is null return false:
        if ((object)p == null)
        {
            return false;
        }

       //Return true if the fields match:
        return (type == p.type);
    }
}

și un exemplu de utilizare:

[DataContract]
public class A
{

    ...

    [DataMember]
    private Dictionary _bees;

    ...

    public B GetB(Type type)
    {
        return _bees[type];
    }

    ...

}

S-ar putea să considerați, de asemenea, folosirea AssemblyQualifiedName în loc de Type.FullName - a se vedea comentariul de la @GreyCloud

0
0
Comentarii (0)
Dzyann
29 ianuarie 2014 в 7:19
2014-01-29T19:19:01+00:00
Mai mult
Sursă
Editează
#21435254

Brian's answer works well if the type is in the same assembly as the call (like GreyCloud pointed out in one of the comments). So if the type is in another assembly you need to use the AssemblyQualifiedName as GreyCloud also pointed out.

Cu toate acestea, deoarece AssemblyQualifiedName salvează versiunea, dacă ansamblurile dvs. au o versiune diferită de cea din șirul în care aveți tipul, nu va funcționa.

În cazul meu a fost o problemă și am rezolvat-o astfel:

string typeName = typeof (MyClass).FullName;

Type type = GetTypeFrom(typeName);

object myInstance = Activator.CreateInstance(type);

Metoda GetTypeFrom

private Type GetTypeFrom(string valueType)
    {
        var type = Type.GetType(valueType);
        if (type != null)
            return type;

        try
        {
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();                

            //To speed things up, we check first in the already loaded assemblies.
            foreach (var assembly in assemblies)
            {
                type = assembly.GetType(valueType);
                if (type != null)
                    break;
            }
            if (type != null)
                return type;

            var loadedAssemblies = assemblies.ToList();

            foreach (var loadedAssembly in assemblies)
            {
                foreach (AssemblyName referencedAssemblyName in loadedAssembly.GetReferencedAssemblies())
                {
                    var found = loadedAssemblies.All(x => x.GetName() != referencedAssemblyName);

                    if (!found)
                    {
                        try
                        {
                            var referencedAssembly = Assembly.Load(referencedAssemblyName);
                            type = referencedAssembly.GetType(valueType);
                            if (type != null)
                                break;
                            loadedAssemblies.Add(referencedAssembly);
                        }
                        catch
                        {
                            //We will ignore this, because the Type might still be in one of the other Assemblies.
                        }
                    }
                }
            }                
        }
        catch(Exception exception)
        {
            //throw my custom exception    
        }

        if (type == null)
        {
            //throw my custom exception.
        }

        return type;
    }

Am postat acest lucru în cazul în care cineva are nevoie de el.

0
0
Comentarii (0)
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
ID
KO
RU
© Answer-ID 2021
Sursă
https://stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire