c# länge - Wie kann ich die korrekte Textdefinition eines generischen Typs mit Reflektion erhalten?




3 Answers

Es gibt keine integrierte Möglichkeit, diese Darstellung im .Net Framework zu erhalten. Nämlich weil es keinen Weg gibt, es richtig zu machen. Es gibt eine gute Anzahl von Konstrukten, die in der C # -Stilsyntax nicht darstellbar sind. Zum Beispiel ist "<> foo" ein gültiger Typname in IL, kann aber nicht in C # dargestellt werden.

Wenn Sie jedoch nach einer ziemlich guten Lösung suchen, kann diese ziemlich schnell manuell implementiert werden. Die folgende Lösung funktioniert für die meisten Situationen. Es wird nicht behandelt

  1. Geschachtelte Typen
  2. Illegale C # -Namen
  3. Ein paar andere Szenarien

Beispiel:

public static string GetFriendlyTypeName(Type type) {
    if (type.IsGenericParameter)
    {
        return type.Name;
    }

    if (!type.IsGenericType)
    {
        return type.FullName;
    }

    var builder = new System.Text.StringBuilder();
    var name = type.Name;
    var index = name.IndexOf("`");
    builder.AppendFormat("{0}.{1}", type.Namespace, name.Substring(0, index));
    builder.Append('<');
    var first = true;
    foreach (var arg in type.GetGenericArguments())
    {
        if (!first)
        {
            builder.Append(',');
        }
        builder.Append(GetFriendlyTypeName(arg));
        first = false;
    }
    builder.Append('>');
    return builder.ToString();
}
meta title

Ich arbeite an der Code-Generierung und stolperte mit Generika. Hier ist eine "vereinfachte" Version dessen, was mich Probleme verursacht.

Dictionary<string, DateTime> dictionary = new Dictionary<string, DateTime>();
string text = dictionary.GetType().FullName;

Mit dem obigen Codeausschnitt ist der Wert von text wie folgt:

 System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, 
 Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.DateTime, mscorlib, 
 Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

(Zeilenumbrüche zur besseren Lesbarkeit hinzugefügt.)

Gibt es eine Möglichkeit, den Typnamen ( type ) in einem anderen Format zu erhalten, ohne die obige Zeichenfolge zu analysieren? Ich wünsche folgendes Ergebnis für den text :

System.Collections.Generic.Dictionary<System.String, System.DateTime>



An diesem Abend spielte ich ein wenig mit Erweiterungsmethoden und ich versuchte eine Antwort auf deine Frage zu finden. Hier ist das Ergebnis: Es ist ein Code ohne Garantie. ;-)

internal static class TypeHelper
{
    private const char genericSpecialChar = '`';
    private const string genericSeparator = ", ";

    public static string GetCleanName(this Type t)
    {
        string name = t.Name;
        if (t.IsGenericType)
        {
            name = name.Remove(name.IndexOf(genericSpecialChar));
        }
        return name;
    }

    public static string GetCodeDefinition(this Type t)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("{0}.{1}", t.Namespace, t.GetCleanName());
        if (t.IsGenericType)
        {
            var names = from ga in t.GetGenericArguments()
                        select GetCodeDefinition(ga);
            sb.Append("<");
            sb.Append(string.Join(genericSeparator, names.ToArray()));
            sb.Append(">");
        }
        return sb.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        object[] testCases = { 
                                new Dictionary<string, DateTime>(),
                                new List<int>(),
                                new List<List<int>>(),
                                0
                            };
        Type t = testCases[0].GetType();
        string text = t.GetCodeDefinition();
        Console.WriteLine(text);
    }
}



Ich glaube nicht, dass .NET etwas eingebaut hat, das dies tun würde, also müssen Sie es selbst tun. Ich denke, dass die Reflexionsklassen genügend Informationen liefern, um den Typnamen in dieser Form zu rekonstruieren.




Related

c# generics reflection