Generics, typedef, C#-way



  • Hallo,

    was ist der C#-way mit sowas umzugehen?

    public class Gnarl
    {
    	// ...
    }
    
    public class Bar<T0>
    {
    	// ...
    }
    
    public class Foo<T1, T2, T3>
    {
    	// ...
    	public bool M<T4, T5>() where T4: T1
    	{
    		return ( true );
    	}
    }
    
    class Entry
    {
    	static void Main()
    	{
    		var specialFoo = new Foo<Dictionary<string, Bar<Gnarl>>, List<double>, Func<int, double, bool, Bar<float>, long>>();
    	}
    
    	static Foo<Dictionary<string, Bar<Gnarl>>, List<double>, Func<int, double, bool, Bar<float>, long>> F( Foo<Dictionary<string, Bar<Gnarl>>, List<double>, Func<int, double, bool, Bar<float>, long>> p )
    	{
    		bool b = new Foo<Dictionary<string, Bar<Gnarl>>, List<double>, Func<int, double, bool, Bar<float>, long>>().M<Dictionary<string, Bar<Gnarl>>, bool>();
    		// ...
    		return new Foo<Dictionary<string, Bar<Gnarl>>, List<double>, Func<int, double, bool, Bar<float>, long>>();
    	}		
    }
    

    In C++ würde man jetzt ein typedef machen und das Ganze wäre noch gut lesbar. Hier sieht man nur noch ein großes Rauschen.
    Die Situation wird noch wilder, wenn ich so einen Typ aus einer Bibliothek herausgebe und dann aus irgendeinem Grund z.B. aus einem int-Typparameter einen long mache. Dann müssen Clients an 100000000 Stellen (ohne Mehrwert) ihren Code anpassen.
    Und die Stellen, wo es Typprobleme gäbe (z.B. wenn ich long -> int ändere), habe ich ja zusätzlich trotzdem, d.h. der Client merkt beim Bauen sowieso, wenn was nicht mehr passt. Darauf muss er nicht durch zig gebrochene Variablendeklarationen hingewiesen werden.


  • Administrator

    void* schrieb:

    was ist der C#-way mit sowas umzugehen?

    Es sein zu lassen. Das ist zumindest meine Erfahrung. Die Generics sind nicht so mächtig wie Templates in C++. Wenn man sie probiert, wie C++ Templates einzusetzen, dann kommt man schnell an Grenzen.

    Falls Foo und Bar in anderen Modulen definiert wurden, dann gibt es theoretisch noch eine Möglichkeit. Man kann lokal einen Alias erstellen:
    http://msdn.microsoft.com/en-us/library/sf0df423.aspx

    Allerdings hast du bereits keine Möglichkeit mehr, wenn der Typ von einem Generic-Parameter der zu definierenden Klasse abhängt. Also ganz einfach:

    class MyClass<T>
    {
      public void Test(Tuple<int, int, int, int, T> tuple)
      {
        // ...
      }
    }
    

    Für diesen Tuple-Typ kann man keinen Alias definieren, weil er abhängig von T ist.

    Grüssli



  • Hi Dravere,

    danke für die klare Antwort.
    Das hatte ich schon angenommen, aber immer noch gehofft, irgendetwas übersehen zu haben.
    Sind vielleicht für eine weitere Sprachversion ('C# 5.0') zusätzliche Features im Bereich generics im Gespräch?


Anmelden zum Antworten