Herdar de uma classe base genérica, aplicar uma restrição e implementar uma interface em C #


117

Esta é uma questão de sintaxe. Eu tenho uma classe genérica que está herdando de uma classe base genérica e está aplicando uma restrição a um dos parâmetros de tipo. Também quero que a classe derivada implemente uma interface. Pela minha vida, não consigo descobrir a sintaxe correta.

Isso é o que eu tenho:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar { ... }

A primeira coisa que me veio à mente foi:

DerivedFoo<T1,T2> : ParentFoo<T1, T2> where T2 : IBar, IFoo { ... }

Mas isso é incorreto, pois faz com que T2 precise implementar IBar e IFoo, não DerivedFoo para implementar IFoo.

Tentei pesquisar um pouco no Google, usar dois-pontos, ponto e vírgula, etc., mas não consegui. Tenho certeza de que a resposta é extremamente simples.


Não pude entender a resposta de @Adam quando olhei uma vez, mas depois de 2 minutos consegui entender o que é, obrigado pela resposta. A classe derivada tem mais de uma implementação, talvez este seja o ponto. De qualquer forma, quero mostrar sua notação para os outros. "class DerivedClass <Type>: ParentClass onde Type: IType". Nada deve estar entre a última classe implementada e a cláusula where.
— nurisezgin de

Respostas:


173

Você inclui a assinatura inteira de sua classe antes de definir restrições genéricas.

class DerivedFoo<T1, T2> : ParentFoo<T1, T2>, IFoo where T2 : IBar
{
    ...
}

5
Para outros, internalizei isso como, uma classe só obtém uma cláusula where, e vai no final para qualquer e todas as restrições de tipo genérico.
— Andy V

@Visser É permitido ter cláusulas where múltiplas, classe Test <T1, T2> onde T1: Interface1 onde T2: Interface2
— bwing

@Visser sim, o que o bwing disse, também cada cláusula where pode ter várias restrições ... então a sintaxe do post original está correta, significa apenas algo diferente que o op queria. where T2 : IBar, IFoo apenas significa que T2deve implementar ambas as interfaces em vez de DerivedFoo<T1,T2> implementarIFoo
— v01pe

18

Minha recomendação: quando você tiver uma dúvida sobre a sintaxe da linguagem C #, leia a especificação; é por isso que o publicamos. Você vai querer ler a seção 10.1.

Para responder à sua pergunta específica, a ordem das coisas em uma declaração de classe é:

  • atributos, entre colchetes
  • modificadores ("público", "estático" e assim por diante)
  • "parcial"
  • "classe"
  • o nome da classe
  • uma lista separada por vírgulas de declarações de parâmetro de tipo dentro de colchetes angulares
  • dois pontos seguidos de uma lista separada por vírgulas de tipos base (classe base e interfaces implementadas, classe base deve ir primeiro se houver)
  • restrições de parâmetro de tipo
  • o corpo da classe, cercado por colchetes
  • um ponto e vírgula

Tudo nessa lista é opcional, exceto "classe", o nome e o corpo, mas tudo deve aparecer nessa ordem se aparecer.


95
Eric, embora eu o respeite muito como profissional e aprecie seus comentários, não posso deixar de ficar frustrado com o que parece ser uma resposta abrasiva. Você está me criticando por escolher fazer uma pergunta em um site de perguntas e respostas de programação em vez de localizar, baixar e pesquisar em um documento Word de 503 páginas altamente técnico enterrado em um link no MSDN. Isso é muito difícil. Este foi o uso mais eficiente do meu tempo e tem a vantagem adicional de poder ajudar alguém mais tarde. O link para as especificações C # Lang para os interessados ​​é: msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
— Dan Rigby

17
Nenhuma crítica foi intencional. Existe um preconceito generalizado na comunicação de texto puro que faz com que declarações simples de fatos pareçam bruscas e abrasivas; Tento ler com caridade quando apresentado a uma lista de fatos úteis e recomendo que você faça o mesmo. Eu mantenho minha recomendação; se você tiver dúvidas sobre sintaxe, a especificação as responde definitivamente e começa com um índice útil para localizar definições de sintaxes específicas.
— Eric Lippert

3
Dan, encontrar a especificação C # é tão simples quanto inserir 'C # Spec' no Google e clicar no botão 'Tô com sorte'. E se você é um desenvolvedor C # profissional, você já deve ter especificações C # em formato PDF em sua máquina. Além disso, também não quero criticar você. Eu não estava acostumado a ler especificações antes, mas comecei a ler graças a Jon, Eric e Pavel que sempre citam a especificação C # para qualquer pergunta. Descobri que a especificação C #, embora às vezes seja difícil de ler, é uma ótima maneira de aprender sobre a linguagem.
— SolutionYogi

@Eric Lippert: Muito justo. Obrigado por sua resposta. Como uma sugestão construtiva, seria útil se a Microsoft integrasse o conteúdo da especificação diretamente no MSDN, além de tê-lo como um download separado. A versão do Visual Studio .Net MSDN tem uma versão integrada da especificação, mas não versões posteriores. Pensei em comprar o livro de Anders Hejlberg, mas com o .Net 4.0 chegando, estou relutante em comprar. amazon.com/C-Programming-Language-3rd/dp/0321562992 Obrigado.
— Dan Rigby

2
C ++ requer que uma declaração de classe termine em um ponto-e-vírgula. Muitos desenvolvedores C # vêm de uma formação em C ++; às vezes seus dedos colocam o ponto-e-vírgula sem que o cérebro se envolva. :-) Há uma série de construções em C # que levam um semi opcional onde C ++ requer um. É basicamente uma conveniência sutil. Suponho que também permite que você chame sutilmente quando uma declaração de tipo está terminando em vez de dizer uma declaração de corpo de método.
— Eric Lippert

8
public interface IFoo {}
public interface IBar {}

public class ParentFoo<T,T1> { }
public class DerivedFoo<T, T1> : ParentFoo<T, T1>, IFoo where T1 : IBar { }

2
public class KeyAndValue<T>
{
    public string Key { get; set; }
    public virtual T Value { get; set; }
}

public class KeyAndValue : KeyAndValue<string>
{
    public override string Value { get; set; }
}

Esta é uma extensão das respostas existentes. O padrão é stringse você não fornecer um tipo. Não implementei uma interface, mas isso não deve exigir nada diferente do normal.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.