ホームページ  >  記事  >  バックエンド開発  >  C# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15

C# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15

php是最好的语言
php是最好的语言オリジナル
2018-08-06 14:57:001471ブラウズ

9. 演算子のオーバーロードに慣れる

独自の型を構築するときは、演算子のオーバーロードを使用できるかどうかを常に考慮する必要があります

10. オブジェクトを作成するときは、コンパレータを実装するかどうかを検討する必要があります

ソートが必要な場合は、2 つのコンパレータ実装があります

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# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15

#または 2 つ目

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);
    }
}

Program の Compare メソッドを呼び出します

11. == と Equals を別の方法で扱います

== か Equals:

値型の場合、型の値が等しい場合は True

参照型の場合、型が同じオブジェクトを指している場合、True

を返しますこれらはすべてオーバーロードできます。

For 文字列のような特別な参照クラスとして、Microsoft はその実際的な重要性が値型にあると考えている可能性があるため、FCL (

Framework ) Class Library) 文字列比較は参照自体ではなく、値比較としてオーバーロードされます

設計の観点から見ると、多くの参照型は文字列型と似ています。同じ ID 番号を持っているので、それは人であると考えます。このとき、Equals メソッドをオーバーロードする必要があります。

一般に、参照型の場合、等しい値の特性を定義する必要があります。 Equals メソッドのみをオーバーライドし、 let == は参照の等価性を示すため、必要な方を比較できます。

演算子「==」と「Equals」は両方とも「値の等価性」と「参照」としてオーバーロードできるため、等価性」を明確にするために、FCL は 2 つのインスタンスが同じ参照であるかどうかを比較するための object.ReferenceEquals(); を提供します。辞書のContainsKeyを判定する場合 キー型のHashCodeなので、その型の特定の値を判定条件にしたい場合はGetHashCodeを再度取得する必要があります もちろんHashCodeを使って判定する方法は他にもあります書き換えないと他の問題が発生する可能性があります。影響

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

Equalsメソッドを書き換える場合、事前にタイプセーフなインターフェイスIEquatableも必要です。 Equals の書き換えバージョンは

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();
    }

}

13 である必要があります。型出力の場合、形式 string

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";
    }
}
static void Main(string[] args)
{
    Person p1 = new Person();
    Console.WriteLine(p1);
    Console.WriteLine(p1.ToString("Chinese",null));
    Console.WriteLine(p1.ToString("English", null));
}

IFormattable インターフェイスを継承した後、ToString にパラメータを渡して呼び出すことができます。

IFormatProvider インターフェイスもありますが、まだ勉強していませんC# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15

14. 浅いコピーと深いコピーを正しく実装する

ディープ コピーであろうとディープ コピーの浅いコピーであろうと、Microsoft は、型が ICloneable インターフェイスを継承して、呼び出し元に明確に「この型はコピーできる」と伝えることを確認しました。

浅いコピー:

出力 p1.child.name は変更された child.name です。

p2 の深いコピー:

C# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15

出力はオリジナルです

ディープ コピーは参照型用です。理論的には、文字列型は参照型です。ただし、参照型の特殊な性質により、 Object.MemberwiseClone はまだそのコピーを作成します。つまり、浅いコピー プロセス中に、文字列をコピーする必要があります。文字列を値型として扱います

C# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-1515。ダイナミックを使用してリフレクションの実装を簡素化します

//记得在类前添加[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;
    }
}

ダイナミックを使用すると、リフレクションを使用して記述されたコードよりも美しく簡潔になることがわかります。また、ダイナミックは初回実行後にキャッシュされるため、複数回の実行の効率も高くなります。

その差は 10 倍近くあります。

ただし、反射回数が少なければ効率は高くなります。

これは 100 回実行した結果です

C# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15しかし、多くの場合、効率は必要ありません。リフレクションの実装を簡素化するために常に動的を使用することをお勧めします。

##関連記事:

C# 学習記録: ライティング高品質なコードの改善と提案の整理 1-3C# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15

C# 学習記録: 高品質なコードの作成と改善案の整理 4-8

以上がC# 学習記録: 高品質のコードの作成と組織の改善に関する提案 9-15の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。