Pergunta

Usando ildasm e um programa C # por exemplo.

static void Main(string[] args)
{

}

dá:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ret
} // end of method Program::Main

O que significa a construção hidebysig fazer?

Foi útil?

Solução

A partir ECMA 335 , secção 8.10.4 da partição 1:

O CTS fornece controle independente sobre ambos os nomes que são visíveis a partir de um tipo de base (de cobertura) e o compartilhamento de espaços de layout no derivado classe (substituir). esconderijo é controlada por marcação de um membro na classe derivada quer como ocultar pelo nome ou esconder por nome e assinatura. Se escondendo é sempre realizada com base no tipo do membro, isto é, derivado campo nomes podem esconder nomes de campos base, mas não nomes de métodos, nomes de propriedades, ou nomes de eventos. Se um membro é derivado hide marcado por nome, membros depois de do mesmo tipo na classe base com o mesmo nome não são visíveis no classe derivada; se o membro é marcada hide pelo nome e assinatura, em seguida, apenas uma membro da mesma espécie com exatamente o mesmo nome e tipo (por campos) ou método de assinatura (por métodos) é escondido da classe derivada. Implementação da distinção entre estas duas formas de esconde inteiramente efectuados por idioma de origem compiladores e a biblioteca reflexão; não tem impacto direto sobre as VES em si.

(Não é imediatamente claro disso, mas meios hidebysig "esconder por nome e assinatura".)

Também na seção 15.4.2.2 da partição 2:

hidebysig é fornecido para o uso de ferramentas e é ignorado pelo VES. isto Especifica que o método declarado couros Todos os métodos da base de classe tipos que têm um método de correspondência assinatura; quando omitida, o método deve esconder todos os métodos do mesmo nome, independentemente da assinatura.

Como um exemplo, suponha que você tem:

public class Base
{
    public void Bar()
    {
    }
}

public class Derived : Base
{
    public void Bar(string x)
    {
    }
}

...

Derived d = new Derived();
d.Bar();

Isso é válido, porque Bar(string) não hide Bar(), porque o compilador C # usa hidebysig. Se usado "esconder pelo nome" semântica, você não seria capaz de chamar Bar() em tudo em uma referência do tipo Derived, embora você ainda pode lançá-lo para a Base e chamá-lo dessa forma.

EDIT: Eu apenas tentei isso por compilar o código acima para uma DLL, ildasming-lo, removendo hidebysig para Bar() e Bar(string), ilasming-lo novamente, em seguida, tentar Bar() telefonema de outro código:

Derived d = new Derived();
d.Bar();

Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments

No entanto:

Base d = new Derived();
d.Bar();

(Sem problemas de compilação.)

Outras dicas

De acordo com a resposta do SKEET, além disso, a razão para isso é que Java e C # permitir que o cliente de uma classe para chamar quaisquer métodos com o mesmo nome, incluindo os de classes base. Considerando C ++ não faz: se os define classe derivada até mesmo um único método com o mesmo nome de um método na classe base, então o cliente não pode chamar diretamente o método da classe base, mesmo que ele não leva os mesmos argumentos. Assim, o recurso foi incluído no CIL para suportar ambas as abordagens a uma sobrecarga.

Em C ++ você pode efetivamente importar um conjunto nomeado de sobrecargas da classe base com uma directiva using, para que se tornem parte do "set sobrecarga" para esse nome método.

De acordo com o Microsoft Docs

Quando um membro em uma classe derivada é declarada com o modificador C # new ou o modificador Shadows Visual Basic, ele pode esconder um membro da mesma nome na classe base. C # peles dos alunos de base por assinatura. Este é, se o membro da classe base tem várias sobrecargas, o único que está escondido é a que tem a assinatura idêntica. Por contraste, Visual Basic oculta todas as sobrecargas de classe base. Assim, IsHideBySig retornos false em um membro declarado com o Shadows Visual Basic modificador, e true em um membro declarado com o modificador C # new.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top