[C#] C #-키워드 사용 가상 + 재정의 vs.

기본 유형 ” virtual” 에서 메소드를 선언 한 다음 하위 유형 에서 일치하는 메소드를 선언 할 때 override단순히 ” new“키워드 를 사용하는 대신 ” “키워드를 사용하여 하위 유형에서 메소드 를 대체하는 것의 차이점은 무엇입니까 ?



답변

“new”키워드는 재정의되지 않으며 기본 클래스 메소드와 관련이없는 새 메소드를 나타냅니다.

public class Foo
{
     public bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public new bool DoSomething() { return true; }
}

public class Test
{
    public static void Main ()
    {
        Foo test = new Bar ();
        Console.WriteLine (test.DoSomething ());
    }
}

재정의를 사용하면 true로 인쇄 될 수 있습니다.

(Joseph Daigle에서 가져온 기본 코드)

따라서 당신이 진정한 다형성을하고 있다면 항상 덮어야 합니다. “새”를 사용해야하는 유일한 방법은 메소드가 기본 클래스 버전과 관련이없는 경우입니다.


답변

나는 항상 이와 같은 것들을 그림으로 더 쉽게 이해합니다.

다시, 조셉 대글의 코드를 가져 와서

public class Foo
{
     public /*virtual*/ bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public /*override or new*/ bool DoSomething() { return true; }
}

그런 다음 다음과 같이 코드를 호출하십시오.

Foo a = new Bar();
a.DoSomething();

참고 : 중요한 것은 객체가 실제로 Bar이지만 변수 유형으로 저장한다는 것입니다Foo (이것은 캐스팅과 유사합니다)

당신이 사용 여부에 따라 다음과 같이 결과가 될 것입니다 virtual/ override또는 new클래스를 선언 할 때.

가상 / 재정의 설명 이미지


답변

다음은 가상 및 비가 상 메소드의 동작 차이를 이해하기위한 코드입니다.

class A
{
    public void foo()
    {
        Console.WriteLine("A::foo()");
    }
    public virtual void bar()
    {
        Console.WriteLine("A::bar()");
    }
}

class B : A
{
    public new void foo()
    {
        Console.WriteLine("B::foo()");
    }
    public override void bar()
    {
        Console.WriteLine("B::bar()");
    }
}

class Program
{
    static int Main(string[] args)
    {
        B b = new B();
        A a = b;
        a.foo(); // Prints A::foo
        b.foo(); // Prints B::foo
        a.bar(); // Prints B::bar
        b.bar(); // Prints B::bar
        return 0;
    }
}


답변

new키워드는 실제로 해당 특정 유형에 존재하는 완전히 새로운 멤버를 작성합니다.

예를 들어

public class Foo
{
     public bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public new bool DoSomething() { return true; }
}

이 방법은 두 가지 유형 모두에 존재합니다. 리플렉션을 사용하고 유형의 멤버를 가져 Bar오면 실제로 DoSomething()똑같이 보이는 두 개의 메소드가 있습니다. 를 사용 new하면 기본 클래스에서 구현을 효과적으로 숨길 수 있으므로 클래스가 Bar(내 예제에서) 파생 될 때 메소드 호출이 아닌 로 base.DoSomething()이동합니다 .BarFoo


답변

virtual / override 는 컴파일러에게 두 가지 방법이 관련되어 있으며 어떤 상황에서는 첫 번째 (가상) 메소드를 호출한다고 생각할 때 실제로 두 번째 (재정의) 메소드를 호출하는 것이 맞다는 것을 컴파일러에게 알려줍니다. 이것이 다형성의 기초입니다.

(new SubClass() as BaseClass).VirtualFoo()

SubClass의 재정의 된 VirtualFoo () 메소드를 호출합니다.

new 는 컴파일러에게 기본 클래스의 메서드와 이름이 같은 파생 클래스에 메서드를 추가하고 있지만 서로 관계가 없다고 알려줍니다.

(new SubClass() as BaseClass).NewBar()

BaseClass의 NewBar () 메서드를 호출합니다.

(new SubClass()).NewBar()

SubClass의 NewBar () 메소드를 호출합니다.


답변

기술적 세부 사항 외에도 가상 / 재정의를 사용하면 디자인에 대한 많은 의미 정보가 전달된다고 생각합니다. 가상 메소드를 선언 할 때 구현 클래스가 기본이 아닌 고유 한 구현을 제공하고자 할 수 있음을 나타냅니다. 마찬가지로 기본 클래스에서 이것을 생략하면 기본 메소드가 모든 구현 클래스에 충분해야한다는 기대를 선언합니다. 마찬가지로 추상 선언을 사용하여 구현 클래스가 자체 구현을 제공하도록 할 수 있습니다. 다시 말하지만, 이것은 프로그래머가 코드 사용을 어떻게 기대하는지에 대해 많은 의사 소통을한다고 생각합니다. 기본 클래스와 구현 클래스를 모두 작성하고 new를 사용하여 자신을 발견하면 부모에서 메소드를 가상으로 만들지 않고 내 의도를 구체적으로 선언하지 않기로 한 결정을 진지하게 다시 생각할 것입니다.


답변

override 키워드와 new 키워드의 차이점은 전자가 메서드를 재정의하고 나중에 키워드를 재정의한다는 점입니다.

자세한 내용은 다음 링크를 확인하십시오.

MSDN기타