Heim  >  Artikel  >  Backend-Entwicklung  >  C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15

C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15

php是最好的语言
php是最好的语言Original
2018-08-06 14:57:001523Durchsuche

9. Gewöhnen Sie sich an das Überladen von Operatoren

Beim Erstellen eigener Typen sollten Sie immer überlegen, ob Sie Operatorüberladung verwenden können

10. Beim Erstellen eines Objekts müssen Sie überlegen, ob Sie einen Komparator implementieren

Wenn Sie sortieren müssen, gibt es zwei Komparatorimplementierungen

class FirstType : IComparable<FirstType>
{
    public string name;
    public int age;
    public FirstType(int age)
    {
        name = "aa";
        this.age = age;
    }

    public int CompareTo(FirstType other)
    {
        return other.age.CompareTo(age);
    }
}

static void Main(string[] args)
{
    FirstType f1 = new FirstType(3);
    FirstType f2 = new FirstType(5);
    FirstType f3 = new FirstType(2);
    FirstType f4 = new FirstType(1);

    List<FirstType> list = new List<FirstType>
    {
        f1,f2,f3,f4
    };

    list.Sort();

    foreach (var item in list)
    {
        Console.WriteLine(item);
    }
}

C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15

oder der zweite Typ

class Program : IComparer<FirstType>
{
    static void Main(string[] args)
    {
        FirstType f1 = new FirstType(3);
        FirstType f2 = new FirstType(5);
        FirstType f3 = new FirstType(2);
        FirstType f4 = new FirstType(1);

        List<FirstType> list = new List<FirstType>
        {
            f1,f2,f3,f4
        };

        list.Sort(new Program());

        foreach (var item in list)
        {
            Console.WriteLine(item);
        }
    }

    int IComparer<FirstType>.Compare(FirstType x, FirstType y)
    {
        return x.age.CompareTo(y.age);
    }
}

Es ruft die Compare-Methode von Program auf

11. Behandeln Sie == und Equals unterschiedlich

Ob es == oder Equals ist:

Wenn für Werttypen die Werte der Typen gleich sind, geben Sie True zurück

Für Referenztypen geben Sie True zurück, wenn die Typen auf dasselbe Objekt verweisen

und sie können beide überladen werden

für Für eine spezielle Referenzklasse wie String könnte Microsoft denken, dass ihre praktische Bedeutung eher einem Werttyp zuzuordnen ist, also in FCL (FRahmenwerk C lass Llibrary ) im String-Vergleich wird als Wertvergleich überlastet, nicht für die Referenz selbst

In Bezug auf das Design haben viele Referenztypen ähnliche String-Typen, wie z Person, seine ID-Nummer Wenn sie gleich sind, betrachten wir es als dieselbe Person. Zu diesem Zeitpunkt müssen wir die Equals-Methode überladen.

Im Allgemeinen müssen wir für Referenztypen definieren Wir sollten nur die Equals-Methode überschreiben und == Referenzgleichheit bedeuten, damit wir vergleichen können, was wir wollen

Da die Operatoren „==" und „Equals" beide überladen werden können als „ „Wertgleichheit“ und „Referenzgleichheit“, in der Reihenfolge Offensichtlich stellt FCL object.ReferenceEquals(); bereit, um zu vergleichen, ob zwei Instanzen dieselbe Referenz sind

12. Beim Umschreiben von Equals müssen Sie auch GetHashCode umschreiben

Bei der Beurteilung von ContainsKey im Wörterbuch wird der HashCode des Schlüsseltyps verwendet. Wenn wir also einen bestimmten Wert im Typ als Beurteilungsbedingung verwenden möchten, müssen wir GetHashCode erneut verwenden Verwenden Sie HashCode, um zu beurteilen, ob sie gleich sind. Um andere Effekte zu erzielen, sollte beim Umschreiben der Equals-Methode auch eine typsichere Schnittstelle IEquatable erstellt werden. Die endgültige Version des Umschreibens von Equals sollte also

public override int GetHashCode()
{
    //这样写是为了减少HashCode重复的概率,至于为什么这样写我也不清楚。。 记着就行
    return (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName +
            "#" + age).GetHashCode();
}

sein. 13. Geben Sie die formatierte Ausgabezeichenfolge

class FirstType : IEquatable<FirstType>
{
    public string name;
    public int age;
    public FirstType(int age)
    {
        name = "aa";
        this.age = age;
    }

    public override bool Equals(object obj)
    {
        return age.Equals(((FirstType)obj).age);
    }

    public bool Equals(FirstType other)
    {
        return age.Equals(other.age);
    }

    public override int GetHashCode()
    {
        return (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName +
                "#" + age).GetHashCode();
    }

}
class Person : IFormattable
{
    public override string ToString()
    {
        return "Default Hello";
    }

    public string ToString(string format, IFormatProvider formatProvider)
    {

        switch (format)
        {
            case "Chinese":
                return "你好";
            case "English":
                return "Hello";
        }
        return "helo";
    }
}

C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15 ein. Nach dem Erben der IFormattable-Schnittstelle können Sie Parameter in ToString übergeben um verschiedene ToStrings aufzurufen, und der obige Standard-ToString wird nicht aufgerufen

Es gibt auch eine IFormatProvider-Schnittstelle, die ich noch nicht studiert habe

14

Ob es sich um eine Deep Copy-Kopie oder eine flache Kopie handelt, Microsoft hat festgestellt, dass der Typ die ICloneable-Schnittstelle erbt, um dem Aufrufer klar zu sagen: Dieser Typ kann kopiert werden

static void Main(string[] args)
{
    Person p1 = new Person();
    Console.WriteLine(p1);
    Console.WriteLine(p1.ToString("Chinese",null));
    Console.WriteLine(p1.ToString("English", null));
}

Flache Kopie:

C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15Die Ausgabe p1.child.name ist der geänderte untergeordnete Name von p2

Tiefe Kopie:

C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15Die Ausgabe ist das Original

Deep Copy ist für Referenztypen. Aufgrund der Besonderheit des Referenztyps handelt es sich jedoch um einen Referenztyp. Object.MemberwiseClone erstellt immer noch eine Kopie dafür. Das heißt, während des flachen Kopiervorgangs sollten wir Strings als Werttypen betrachten

15. Verwenden Sie Dynamic, um die Reflexionsimplementierung zu vereinfachen

//记得在类前添加[Serializable]的标志
[Serializable]
class Person : ICloneable
{
    public string name;

    public Child child;

    public object Clone()
    {
        //浅拷贝
        return this.MemberwiseClone();
    }

    /// <summary>
    /// 深拷贝
    /// 我也不清楚为什么这样写
    /// </summary>
    /// <returns></returns>
    public Person DeepClone()
    {
        using (Stream objectStream = new MemoryStream())
        {
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(objectStream, this);
            objectStream.Seek(0, SeekOrigin.Begin);
            return formatter.Deserialize(objectStream) as Person;
        }
    }
}

[Serializable]
class Child
{
    public string name;
    public Child(string name)
    {
        this.name = name;
    }

    public override string ToString()
    {
        return name;
    }
}

Es ist ersichtlich, dass die Verwendung von Dynamic schöner und prägnanter ist als der mit Reflektion geschriebene Code und dass er mehrmals ausgeführt werden kann. Die Effizienz ist auch höher, da Dynamic nach der ersten Ausführung zwischengespeichert wird

Der Unterschied beträgt fast das Zehnfache

C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15Aber wenn die Anzahl der Reflexionen geringer ist, ist die Effizienz höher

Dies ist das Ergebnis von 100 Durchgängen

C#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15In vielen Fällen ist Effizienz jedoch nicht erforderlich. Es wird immer empfohlen, Dynamik zu verwenden, um die Implementierung der Reflexion zu vereinfachen.

Verwandte Artikel:

C#-Lernaufzeichnung: 1-3 Vorschläge zur Verbesserung und Organisation von hochwertigem Code

C#-Lernaufzeichnung: Verfassen hochwertiger Code-Verbesserungsvorschläge 4-8

Das obige ist der detaillierte Inhalt vonC#-Lernprotokoll: Vorschläge zum Schreiben und Verbessern von hochwertigem Code 9-15. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn