Did you know?



  • Habt ihr gewusst, dass ein Indexer params benutzen kann?

    public class Foobar
    {
        public Foobar()
        {
            this.FooDic = new Dictionary<string, int>();
        }
        public Dictionary<string, int> FooDic { get; set; }
        public IEnumerable<int> this[params string[] keys]
        {
            get 
            {
                return keys.Select(k => this.FooDic[k]);
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Foobar fb = new Foobar();
            fb.FooDic.Add("1", 1);
            fb.FooDic.Add("2", 2);
    
            foreach (int number in fb["1", "2"])
            {
                Console.WriteLine(number);
            }
        }
    }
    


  • Neee, nicht gewusst.
    Hier mit setter:

    class wtf<T,U> : IEnumerable<KeyValuePair<T,U>>
    {
    	private Dictionary<T, U> dic = new Dictionary<T, U>();
    
    	public U[] this[params T[] param]
    	{
    		get 
    		{
    			return param.Select(key => dic[key]).ToArray(); 
    		}
    		set 
    		{
    			for (int i = 0; i < value.Length; ++i)
    			{
    				if (dic.ContainsKey(param[i]))
    					dic[param[i]] = value[i];
    				else
    					dic.Add(param[i], value[i]);
    			}
    		}
    	}
    
    	public IEnumerator<KeyValuePair<T, U>> GetEnumerator()
    	{
    		return dic.GetEnumerator();
    	}
    
    	System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    	{
    		return dic.GetEnumerator();
    	}
    }
    
    class Program
    {
    	static void Main(string[] args)
    	{
    		wtf<string, int> v = new wtf<string, int>();
    
    		v["hallo", "welt"] = new[] { 23, 42 };
    		v["a"] = new[] { 4711 };
    		v["eins", "zwei", "drei"] = new[] { 1, 2, 3 };
    		v["zwei"] = new[] { 22222 };
    
    		foreach (var i in v)
    			Console.WriteLine(i.ToString());
    
    		Console.WriteLine("----");
    
    		foreach (var i in v["hallo", "drei"])
    			Console.WriteLine(i);
    
    		Console.ReadKey(true);
    	}
    }
    

    Wie könnte man das hässliche new[]{...} loswerden?



  • Mit einem "Hack". Ist aber fraglich ob man sowas will und ob es schöner ist.

    //...
    public U[] this[params U[] param]
    {
        get
        {
            return param;
        }
    }
    //...
    v["hallo", "welt"] = v[23, 42];
    

  • Administrator

    Gewusst. Kennst du dies? Dürfte dir dann vielleicht auch ein Licht aufgehen, wieso params erlaubt ist 😉

    class Test
    {
      public int this[int x]
      {
        get { return 0; }
      }
    
      public int get_Item(int x)
      {
        return 0;
      }
    }
    
    public class Program
    {
      public static void Main(string[] args)
      {
        var t = new Test();
        var r = t[0];
      }
    }
    
    ------ Build started: Project: TestProject, Configuration: Debug x86 ------
    C:\...\Program.cs(5,5): error CS0082: Type 'Test' already reserves a member called 'get_Item' with the same parameter types
    C:\...\Program.cs(8,14): (Related location)
    
    Compile complete -- 1 errors, 0 warnings
    

    Grüssli



  • Wir können ja hier mal ein paar Sprachfeatures sammeln, die man in der freien Wildbahn selten oder nie antrifft.

    Wusstet ihr, dass man mit | und & die Short-circuit evaluation aushebeln kann?

    class Program 
    {
    	static bool f1()
    	{
    		Console.Write("f1 ");
    		return true;
    	}
    
    	static bool f2()
    	{
    		Console.Write("f2 ");
    		return false;
    	}
    
    	static void Main(string[] args)
    	{
    		if (f1() || f2()) { } //Ausgabe: f1
    		Console.WriteLine();
    
    		if (f1() | f2()) { } //Ausgabe: f1 f2
    		Console.WriteLine();
    
    		if (f2() && f1()) { } //Ausgabe: f2
    		Console.WriteLine();
    
    		if (f2() & f1()) { } //Ausgage: f2 f1
    		Console.WriteLine();
    
    		Console.ReadKey(true);
    	}
    }
    


  • µ schrieb:

    Wusstet ihr, dass man mit | und & die Short-circuit evaluation aushebeln kann?

    Der Begriff sagt mir jetzt gar nichts, hast du ne Definition dafuer?





  • µ schrieb:

    Short-circuit evaluation aushebeln

    Das zählt nicht als Aushebeln. Es ist der Normalfall.

    Die "Short-circuit"-operatoren sind vielmehr eine Besser-als-normal-Variante, an die wir uns allerdings längst gewöhnt haben.



  • Enums können Extensionmethods haben.

    enum AnEnum
    {
        Element1,
        Element2
    }
    static class Extension
    {
        public static string EnumExtension(this AnEnum e)
        {
            return "Enum Extension";
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(AnEnum.Element1.EnumExtension());
        }
    }
    


  • Nützlich, aber sieht man eher selten:

    var irgendwas = GetResult() ?? String.Empty;
    


  • loks schrieb:

    Nützlich, aber sieht man eher selten:

    var irgendwas = GetResult() ?? String.Empty;
    

    Liegt wahrscheinlich daran, das es für die wenigsten lesbar ist.

    Ich bevorzuge da eher die langform. Entweder wie unten aufgeführt oder die ganz lange. 😉

    var sResult = GetResult();
    var irgendwas = !String.IsNullOrEmpty(sResult) ? sResult : string.Empty;
    


  • inflames2k schrieb:

    loks schrieb:

    var irgendwas = GetResult() ?? String.Empty;
    

    Liegt wahrscheinlich daran, das es für die wenigsten lesbar ist.

    Du meinst, dass die wenigsten wissen, wie ihre Sprache funktioniert? Weil: Lesbar ist das auf jeden Fall, sehr gut sogar.



  • inflames2k schrieb:

    loks schrieb:

    Nützlich, aber sieht man eher selten:

    var irgendwas = GetResult() ?? String.Empty;
    

    Liegt wahrscheinlich daran, das es für die wenigsten lesbar ist.

    Ich bevorzuge da eher die langform. Entweder wie unten aufgeführt oder die ganz lange. 😉

    var sResult = GetResult();
    var irgendwas = !String.IsNullOrEmpty(sResult) ? sResult : string.Empty;
    

    Das Beispiel an sich ist natürlich Sinnfrei, aber im Bezug auf Lesbarkeit gewinnt das doch um Längen gegen den Mehrzeiler.

    class A 
    {
        public String Name { get; set; }
    
        public String Strasse{ get; set; }
    }
    
    void test()
    {
        A a = new A() 
        { 
          Name = GetName() ?? String.Empty,
          Strasse = GetStrasse() ?? String.Empty
         };
    }
    


  • using kann gestapelt werden.

    using(StreamReader sr = new StreamReader(".txt"))
    using(StreamWriter sw = new StreamWriter(".txt"))
    {
        sr.ReadLine();
        sw.WriteLine();
    }
    


  • Nicht gestapelt, sondern verschachtelt (wie andere Anweisungen z.B. for, if, while etc. auch).

    Dein Beispiel entspricht also voll ausgeschrieben:

    using(StreamReader sr = new StreamReader(".txt"))
    {
        using(StreamWriter sw = new StreamWriter(".txt"))
        {
            var line = sr.ReadLine();
            sw.WriteLine(line);
        }
    }
    

    Und wie man sieht wäre dann folgendes besser

    using(StreamReader sr = new StreamReader(".txt"))
    {
        var line = sr.ReadLine();
    
        using(StreamWriter sw = new StreamWriter(".txt"))
        {
            sw.WriteLine(line);
        }
    }
    

    (oder noch gekürzt ohne die inneren geschweiften Klammern)



  • Mit stapeln meinte ich auch eher, dass man es genau übereinander schreiben kann, was hilfreich sein kann, wenn man 3-4 using-Blöcke brauch und nicht möchte, dass der Code unnötig weit nach rechts rückt.
    Aber deine Erklärung ist natürlich richtig.



  • freaky schrieb:

    ... was hilfreich sein kann, wenn man 3-4 using-Blöcke brauch ...

    3-4, herzig 😉

    using (var seedReader = new StreamFileReader(m_seedStreams[level], false))
    				using (var seedSignatureReader = new StreamFileReader(m_seedStreams[level + 1], false))
    				using (var sourceReader = CreateSourceReader(level))
    				using (var countingSourceReader = new CountingFileReader(sourceReader, false))
    				using (var sourceSignatureReader = new StreamFileReader(sourceSignatureStream, false))
    				using (var targetSink = new StreamByteSink(targetStream, false))
    				using (var reconstructingNeedSink = new ReconstructingNeedSink())
    				using (var skippingNeedSink = new SkippingNeedSink())
    				using (var batchShapingNeedSink = new BatchShapingNeedSink())
    				{
    

    ps:
    Ist euch schonmal folgendes abgegangen?

    try
        {
            ...
        }
        finally { CleanupThiny1ThatCanThrow(); }
        finally { CleanupThiny2ThatCanThrow(); }
        finally { CleanupThiny3ThatCanThrow(); }
        finally { CleanupThiny4ThatCanThrow(); }
    

    ?



  • Na ja, das ist ja nur ein Frage der Code-Formatierung:

    for (int i=0; i<10; i++)
    for (int j=0; j<10; j++)
    Console.WriteLine("{0}, {1}", i, j)
    

    oder

    if (x > y)
    if (x > z)
    x = y + z;
    

    :p



  • Dann zeig mal wie das für try-finally aussehen würde.

    Davon abgesehen: jegliche Formatierung die VS nicht kann ist ziemlich uninteressant. Ich kämpfe nicht mehr gegen das System.
    Wenns Plugins gibt die besser formatieren und sich nahtlos integrieren (Auto-Format beim Tippen von ";" usw.), OK. Immer noch doof für Leute die das Plugin dann nicht haben, aber damit könnte ich leben.

    Aber manuell formatiere ich nix mehr was das nächste Ctrl+K, Ctrl+F nicht überlebt. Bin ja kein Masochist.

    ps: Ich find's schrecklich dass man bei VS die Formatierungsregeln nicht zum Projekt dazuhängen kann. Wenn jmd. ein Plugin kennt das hier abhilft: bitte melden 🙂



  • Für automatische Code-Formatierung im VS empfehle ich {url=http://www.codemaid.net/]CodeMaid[/url].

    PS: Ich bezog mich bei meinem vorherigen Beitrag auf den von freaky.
    Selber nutze ich bei mehreren [i]using[i] auch eure Schreibweise - mir ging es nur um das Verständnis.


Anmelden zum Antworten