IT story

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

hot-time 2020. 5. 8. 08:22
반응형

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

The method exists on both types. When you use reflection and get the members of type Bar, you will actually find 2 methods called DoSomething() that look exactly the same. By using new you effectively hide the implementation in the base class, so that when classes derive from Bar (in my example) the method call to base.DoSomething() goes to Bar and not Foo.


virtual / override tells the compiler that the two methods are related and that in some circumstances when you would think you are calling the first (virtual) method it's actually correct to call the second (overridden) method instead. This is the foundation of polymorphism.

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

Will call the SubClass's overriden VirtualFoo() method.

new tells the compiler that you are adding a method to a derived class with the same name as a method in the base class, but they have no relationship to each other.

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

Will call the BaseClass's NewBar() method, whereas:

(new SubClass()).NewBar()

Will call the SubClass's NewBar() method.


Beyond just the technical details, I think using virtual/override communicates a lot of semantic information on the design. When you declare a method virtual, you indicate that you expect that implementing classes may want to provide their own, non-default implementations. Omitting this in a base class, likewise, declares the expectation that the default method ought to suffice for all implementing classes. Similarly, one can use abstract declarations to force implementing classes to provide their own implementation. Again, I think this communicates a lot about how the programmer expects the code to be used. If I were writing both the base and implementing classes and found myself using new I'd seriously rethink the decision not to make the method virtual in the parent and declare my intent specifically.


The difference between the override keyword and new keyword is that the former does method overriding and the later does method hiding.

Check out the folllowing links for more information...

MSDN and Other


  • new keyword is for Hiding. - means you are hiding your method at runtime. Output will be based base class method.
  • override for overriding. - means you are invoking your derived class method with the reference of base class. Output will be based on derived class method.

My version of explanation comes from using properties to help understand the differences.

override is simple enough, right ? The underlying type overrides the parent's.

new is perhaps the misleading (for me it was). With properties it's easier to understand:

public class Foo
{
    public bool GetSomething => false;
}

public class Bar : Foo
{
    public new bool GetSomething => true;
}

public static void Main(string[] args)
{
    Foo foo = new Bar();
    Console.WriteLine(foo.GetSomething);

    Bar bar = new Bar();
    Console.WriteLine(bar.GetSomething);
}

Using a debugger you can notice that Foo foo has 2 GetSomething properties, as it actually has 2 versions of the property, Foo's and Bar's, and to know which one to use, c# "picks" the property for the current type.

If you wanted to use the Bar's version, you would have used override or use Foo foo instead.

Bar bar has only 1, as it wants completely new behavior for GetSomething.


Not marking a method with anything means: Bind this method using the object's compile type, not runtime type (static binding).

Marking a method with virtual means: Bind this method using the object's runtime type, not compile time type (dynamic binding).

Marking a base class virtual method with override in derived class means: This is the method to be bound using the object's runtime type (dynamic binding).

Marking a base class virtual method with new in derived class means: This is a new method, that has no relation to the one with the same name in the base class and it should be bound using object's compile time type (static binding).

Not marking a base class virtual method in the derived class means: This method is marked as new (static binding).

Marking a method abstract means: This method is virtual, but I will not declare a body for it and its class is also abstract (dynamic binding).

참고URL : https://stackoverflow.com/questions/159978/c-sharp-keyword-usage-virtualoverride-vs-new

반응형