developer tip

메소드 서명의 새 키워드

optionbox 2020. 7. 27. 07:51
반응형

메소드 서명의 새 키워드


리팩토링을 수행하는 동안 아래 예제와 같은 메소드를 작성했습니다. 편의상 데이터 유형이 변경되었습니다.

나는 이전에 이와 같은 과제 진술을했다 :

MyObject myVar = new MyObject();

우연히 이것으로 리팩토링되었습니다.

private static new MyObject CreateSomething()
{
  return new MyObject{"Something New"};
}

이것은 내 부분에 잘라 내기 / 붙여 넣기 오류의 결과이지만 new키워드 in private static new은 유효하고 컴파일됩니다.

질문 : new키워드는 메소드 서명에서 무엇을 의미합니까? C # 3.0에 도입 된 것으로 가정합니까?

이것은 어떻게 다른 override가요?


MSDN의 새로운 키워드 참조 :

MSDN 참조

다음은 Microsoft MVP에서 인터넷에서 찾은 예입니다. Link to Original

public class A
{
   public virtual void One();
   public void Two();
}

public class B : A
{
   public override void One();
   public new void Two();
}

B b = new B();
A a = b as A;

a.One(); // Calls implementation in B
a.Two(); // Calls implementation in A
b.One(); // Calls implementation in B
b.Two(); // Calls implementation in B

재정의는 매우 특정한 경우에만 사용할 수 있습니다. MSDN에서 :

비가 상 또는 정적 메소드를 대체 할 수 없습니다. 재정의 된 기본 방법은 가상, 추상 또는 재정의 여야합니다.

따라서 비 가상적 및 정적 메소드를 '재정의'하려면 'new'키워드가 필요합니다.


아니요, 실제로는 "새"가 아닙니다 (말장난을 용서하십시오). 기본적으로 메소드를 "숨기는"데 사용됩니다. IE :

public class Base
{
   public virtual void Method(){}
}

public class Derived : Base
{
   public new void Method(){}
}

그런 다음이 작업을 수행하면

Base b = new Derived();
b.Method();

Base의 메소드는 파생 된 메소드가 아닌 호출 될 메소드입니다.

더 많은 정보 : http://www.akadia.com/services/dotnet_polymorphism.html

다시 편집 : 내가 준 예에서 "new"를 사용하는 대신 "override"하는 경우 b.Method (); 파생 클래스의 메서드는 다형성 때문에 호출됩니다.


As others explained, it is used to hide an existing method. It is useful for overriding a method that isn't virtual in the parent class.

Keep in mind that creating a "new" member is not polymorphic. If you cast the object to the base type, it will not use the derived type's member.

If you have a base class:

public class BaseClass
{
    public void DoSomething() { }
}

And then the derived class:

public class DerivedType : BaseClass
{
    public new void DoSomething() {}

}

If you declare a type of DerivedType and then cast it, the method DoSomething() isn't polymorphic, it will call the base class' method, not the derived one.

BaseClass t = new DerivedType();
t.DoSomething();// Calls the "DoSomething()" method of the base class.

From the docs:

If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.

What this means in practice:

If you inherit from another class and you have a method that shares the same signature you can define it as 'new' so that it independent from the parent class. This means that if you have a reference to the 'parent' class then that implementation will be executed, if you have a reference to the child class then that implementation will be executed.

Personally I try to avoid the 'new' keyword as it normally means I've got my class hierarchy wrong, but there are times when it can be useful. One place is for versioning and backwards compatibility.

There's lot of information in the MSDN for this.


It means the method replaces a method by the same name inherited by the base class. In your case, you probably don't have a method by that name in the base class, meaning the new keyword is totally superfluous.


Long story short -- it's NOT required, it changes NO behavior, and it is PURELY there for readability.

That's why in VS you will see a little squiggly, yet your code will compile and run perfectly fine and as expected.

One has to wonder if it was really worth creating the new keyword when all it means is the developer's acknowledging "Yes, I know I'm hiding a base method, yes I know I'm not doing anything related to virtual or overriden (polymorphism) -- I really want to just create it's own method".

It's a bit bizarre to me, but maybe only because I come from a Java background and there's this fundamental difference between C# inheritance and Java: In Java, methods are virtual by default unless specified by final. In C#, methods are final/concrete by default unless specified by virtual.


From MSDN:

Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.


Be careful of this gotcha.
You have a method defined in an interface that is implemented in a base class. You then create a derived class that hides the interface's method, but don't specifically declare the derived class as implementing the interface. If you then call the method via a reference to the interface, the base class's method will be called. However if your derived class does specifically implement the interface, then its method will be called whichever type of reference is used.

interface IMethodToHide
{
    string MethodToHide();
}

class BaseWithMethodToHide : IMethodToHide
{
    public string MethodToHide()
    {
        return "BaseWithMethodToHide";
    }
}

class DerivedNotImplementingInterface   : BaseWithMethodToHide
{
    new public string MethodToHide()
    {
        return "DerivedNotImplementingInterface";
    }
}

class DerivedImplementingInterface : BaseWithMethodToHide, IMethodToHide
{
    new public string MethodToHide()
    {
        return "DerivedImplementingInterface";
    }
}

class Program
{
    static void Main()
    {
        var oNoI = new DerivedNotImplementingInterface();
        IMethodToHide ioNoI = new DerivedNotImplementingInterface();

        Console.WriteLine("reference to the object type DerivedNotImplementingInterface calls the method in the class " 
            + oNoI.MethodToHide());
        // calls DerivedNotImplementingInterface.MethodToHide()
        Console.WriteLine("reference to a DerivedNotImplementingInterface object via the interfce IMethodToHide calls the method in the class " 
            + ioNoI.MethodToHide());
        // calls BaseWithMethodToHide.MethodToHide()
        Console.ReadLine();

        var oI = new DerivedImplementingInterface();
        IMethodToHide ioI = new DerivedImplementingInterface();

        Console.WriteLine("reference to the object type DerivedImplementingInterface calls the method in the class " 
            + oI.MethodToHide());
        // calls DerivedImplementingInterface.MethodToHide()
        Console.WriteLine("reference to a DerivedImplementingInterface object via the interfce IMethodToHide calls the method in the class " 
            + ioI.MethodToHide());
        // calls DerivedImplementingInterface.MethodToHide()
        Console.ReadLine();

    }
}

참고URL : https://stackoverflow.com/questions/1014295/new-keyword-in-method-signature

반응형