nova palavra-chave na assinatura do método

Ao realizar uma refatoração, acabei criando um método como o exemplo abaixo. O tipo de dados foi alterado para simplificar.

Eu já tinha uma declaração de atribuição como esta:

MyObject myVar = new MyObject(); 

Foi refatorado para isso por acidente:

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

Isso foi resultado de um erro de recortar / colar da minha parte, mas a new palavra-chave em private static new é válida e compila.

Pergunta : O que a new palavra-chave significa em uma assinatura de método? Eu suponho que é algo introduzido no C # 3.0?

Como isso difere do override ?

Nova referência de palavra-chave do MSDN:

Referência MSDN

Aqui está um exemplo que encontrei na net de um MVP da Microsoft que fazia sentido: Link para 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 

Override só pode ser usado em casos muito específicos. Do MSDN:

Você não pode replace um método não virtual ou estático. O método base substituído deve ser virtual, abstrato ou anular.

Portanto, a palavra-chave “new” é necessária para permitir que você “substitua” methods não-virtuais e estáticos.

Não, na verdade não é “novo” (com o perdão do trocadilho). É basicamente usado para “esconder” um método. IE:

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

Se você fizer isso:

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

O método na Base é o que será chamado, NÃO o do derivado.

Mais algumas informações: http://www.akadia.com/services/dotnet_polymorphism.html

Re sua edição: No exemplo que eu dei, se você fosse “replace” em vez de usar “novo”, então quando você chama b.Method (); O método da class derivada seria chamado por causa do polymorphism.

Como outros explicaram, é usado para ocultar um método existente. É útil para replace um método que não é virtual na class pai.

Tenha em mente que criar um “novo” membro não é polimórfico. Se você converter o object para o tipo base, ele não usará o membro do tipo derivado.

Se você tem uma class base:

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

E então a class derivada:

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

Se você declarar um tipo de DerivedType e, em seguida, DerivedType -lo, o método DoSomething() não é polimórfico, ele chamará o método da class base, não o derivado.

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

Dos docs:

Se o método na class derivada for precedido pela nova palavra-chave, o método será definido como independente do método na class base.

O que isso significa na prática:

Se você herdar de outra class e tiver um método que compartilhe a mesma assinatura, poderá defini-la como ‘nova’ para que seja independente da class pai. Isso significa que, se você tiver uma referência à class ‘pai’, essa implementação será executada, se você tiver uma referência à class filha, essa implementação será executada.

Pessoalmente eu tento evitar a palavra-chave ‘new’, pois normalmente significa que minha hierarquia de classs está errada, mas há momentos em que isso pode ser útil. Um lugar é para version control e compatibilidade com versões anteriores.

Há muita informação no MSDN para isso .

Isso significa que o método substitui um método pelo mesmo nome herdado pela class base. No seu caso, você provavelmente não tem um método com esse nome na class base, o que significa que a nova palavra-chave é totalmente supérflua.

Longa história curta – não é necessária, não muda o comportamento, e é perfeitamente lá para legibilidade.

É por isso que no VS você vai ver um pouco rabugento, mas seu código irá compilar e rodar perfeitamente bem e como esperado.

É de se perguntar se valeu a pena criar a new palavra-chave quando tudo o que ela significa é o reconhecimento do desenvolvedor “Sim, eu sei que estou escondendo um método base, sim eu sei que não estou fazendo nada relacionado ao virtual ou overriden (polymorphism ) – Eu realmente quero apenas criar seu próprio método “.

É um pouco bizarro para mim, mas talvez só porque eu venho de um fundo Java e há essa diferença fundamental entre inheritance C# e Java : Em Java , os methods são virtuais por padrão, a menos que especificado pelo final . Em C# , os methods são final / concreto por padrão, a menos que especificado por virtual .

Do MSDN :

Use o novo modificador para ocultar explicitamente um membro herdado de uma class base. Para ocultar um membro herdado, declare-o na class derivada usando o mesmo nome e modifique-o com o novo modificador.

Tenha cuidado com essa pegadinha.
Você tem um método definido em uma interface que é implementada em uma class base. Em seguida, você cria uma class derivada que oculta o método da interface, mas não declara especificamente a class derivada como implementando a interface. Se você chamar o método por meio de uma referência à interface, o método da class base será chamado. No entanto, se a sua class derivada implementar especificamente a interface, seu método será chamado de acordo com o tipo de referência usado.

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