>백엔드 개발 >C#.Net 튜토리얼 >C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15

C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15

php是最好的语言
php是最好的语言원래의
2018-08-06 14:57:001566검색

9. 연산자 오버로드에 익숙해지세요

자신만의 유형을 만들 때 연산자 오버로딩을 사용할 수 있는지 항상 고려해야 합니다

10 객체를 만들 때 비교기를 구현할지 여부를 고려해야 합니다

. 정렬이 필요한 경우 두 개의 비교기 구현이 있습니다

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

또는 두 번째 구현

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

11의 Compare 메서드를 호출합니다. ==와 Equals를 다르게 처리합니다

==인지 Equals인지 여부입니다. :

값 유형의 경우 유형의 값이 같으면 True를 반환합니다.

참조 유형의 경우 유형이 동일한 개체를 가리키면 True를 반환하고

모두 오버로드될 수 있습니다.

문자열과 같은 특별한 참조 클래스라고 Microsoft에서는 생각할 수 있습니다. 실용적인 의미는 값 유형에 더 가깝기 때문에 FCL(Framework Class Library)에서는 문자열 비교가 값 비교로 오버로드됩니다. 레퍼런스 자체보다

디자인적인 측면에서 많은 레퍼런스 유형이 문자열 유형과 유사합니다. 예를 들어, 동일한 ID 번호를 가진 사람은 이 때 동일한 사람으로 간주됩니다.

일반적으로 참조 유형의 경우 동일한 값의 특성을 정의하고 Equals 메서드만 재정의하고 ==가 참조 동등성을 나타내도록 하여 원하는 것을 비교할 수 있도록 해야 합니다.

연산자 "=="와 "Equals"는 모두 "값 동등"과 "참조 동등"으로 포함되어 재정의될 수 있으므로 명확성을 위해 FCL은 두 인스턴스가 동일한 참조인지 비교하기 위해 object.ReferenceEquals()를 제공합니다.

12. Equals를 다시 작성할 때 GetHashCode도 다시 작성해야 합니다

사전에서 ContainsKey를 판단할 때 키 유형의 HashCode를 사용하므로 해당 유형의 특정 값을 판단 조건으로 사용하려면 다음을 수행해야 합니다. 물론, HashCode를 사용하여 동일한지 판단하는 다른 메서드도 있습니다. 다시 작성하지 않으면 다른 효과가 발생할 수 있습니다

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

Equals 메서드를 다시 작성하는 동안 형식이 안전한 인터페이스 IEquatable
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이어야 합니다. 형식 출력 형식 문자열의 경우

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

C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15

IFormattable 인터페이스를 상속한 후 위의 기본 ToString을 호출하기 위해 ToString에 매개 변수를 전달할 수 있습니다.

아직 연구하지 않은 IFormatProvider 인터페이스도 있습니다

14. 얕은 복사와 깊은 복사를 올바르게 구현합니다.

딥 복사본이든 얕은 복사본이든 Microsoft는 배웠습니다. 유형을 사용하여 ICloneable 인터페이스를 상속하여 호출자에게 명확하게 알리려면 유형을 복사할 수 있습니다

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

얕은 복사:

C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15

출력 p1.child.name은 p2의 변경된 child.name입니다

딥 복사 :

C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15

출력은 원본입니다.

Deep 복사본은 이론적으로 참조 유형에 대한 것입니다. 위의 문자열 유형은 참조 유형이지만 참조 유형의 특수성으로 인해 Object.MemberwiseClone은 여전히 ​​복사본을 생성합니다. 이는 얕은 복사 과정에서 문자열을 값 유형으로 간주해야 함을 의미합니다

15. 동적을 사용하여 리플렉션 구현을 단순화합니다

static void Main(string[] args)
{
    //使用反射
    Stopwatch watch = Stopwatch.StartNew();
    Person p1 = new Person();
    var add = typeof(Person).GetMethod("Add");
    for (int i = 0; i < 1000000; i++)
    {
        add.Invoke(p1, new object[] { 1, 2 });
    }
    Console.WriteLine(watch.ElapsedTicks);


    //使用dynamic
    watch.Reset();
    watch.Start();
    dynamic d1 = new Person();
    for (int i = 0; i < 1000000; i++)
    {
        d1.Add(1, 2);
    }
    Console.WriteLine(watch.ElapsedTicks);
}

리플렉션을 사용하여 작성된 코드보다 동적을 사용하는 것이 더 아름답고 간결하다는 것을 알 수 있습니다. 동적은 첫 번째 실행 후에 캐시되기 때문에 여러 번 실행하면 효율성이 높아집니다

차이는 거의 10배입니다C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15

하지만 반사 횟수가 적으면 효율성이 높아집니다

이것은 100번 실행한 결과C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15

그러나 많은 경우 효율성은 필요하지 않으며 리플렉션 구현을 단순화하기 위해 항상 동적을 사용하는 것이 좋습니다

관련 기사 :

C# 학습 기록: 고품질 코드 개선 제안 작성 1- 3

C# 학습 기록: 고품질 코드 개선 제안 작성 4-8

위 내용은 C# 학습 기록: 고품질 코드 작성 및 개선을 위한 제안 9-15의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.