Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo aborda os seguintes erros do compilador:
- CS0080: Não são permitidas restrições em declarações não genéricas.
- CS0081: A declaração do parâmetro de tipo deve ser um identificador, não um tipo.
- CS0224: Um método com vararg não pode ser genérico, ser de tipo genérico ou ter um parâmetro params.
-
CS0304: Não é possível criar uma instância do tipo variável porque não tem a
new()restrição. - CS0305: Usar o tipo genérico requer argumentos do tipo N.
- CS0306: O tipo não pode ser usado como argumento de tipo.
- CS0307: O identificador não é um método genérico. Se pretendia uma lista de expressões, use parênteses à volta da expressão.
- CS0308: O tipo ou método não genérico não pode ser usado com argumentos de tipo.
- CS0310: O tipo deve ser um tipo não abstrato com um construtor público sem parâmetros para poder ser usado como parâmetro no tipo ou método genérico.
-
CS0311:O tipo não pode ser usado como parâmetro
Tde tipo no tipo genérico ou método. Não existe conversão de referência implícita do tipo 1 para o tipo 2. - CS0312: O tipo 'tipo1' não pode ser usado como parâmetro de tipo no tipo genérico ou método. O tipo anulável 'tipo1' não satisfaz a restrição.
- CS0313: O tipo 'tipo1' não pode ser usado como parâmetro de tipo no tipo genérico ou método. O tipo anulável 'tipo1' não satisfaz a restrição. Tipos anuláveis não conseguem satisfazer quaisquer restrições de interface.
- CS0314: O tipo não pode ser usado como parâmetro de tipo no tipo genérico ou método. Não existe conversão para boxing nem conversão de parâmetros de tipo.
-
CS0315: O tipo não pode ser usado como parâmetro
Tde tipo no tipo genérico ou método. Não há conversão para boxe. -
CS0401: A
new()restrição deve ser a última restrição especificada. -
CS0403: Não é possível converter nulo em parâmetro de tipo porque pode ser um tipo de valor não anulável. Considera usar
default(T)em vez disso. - CS0405: Restrição duplicada para o parâmetro de tipo.
- CS0412: Parâmetro: um parâmetro, variável local ou função local não pode ter o mesmo nome que um parâmetro de tipo de método.
-
CS0413: O parâmetro de tipo não pode ser usado com o
asoperador porque não tem uma restrição de tipo de classe nem umaclassrestrição. - CS0417: Identificador: não pode fornecer argumentos ao criar uma instância de um tipo de variável.
-
CS0449: As
classrestrições ,struct,unmanaged,notnull, edefaultnão podem ser combinadas ou duplicadas, e devem ser especificadas primeiro na lista de restrições. -
CS0450: Parâmetro de Tipo: não pode especificar ambos uma classe de restrição e a restrição
classoustruct. -
CS0451: A
new()restrição não pode ser usada com astructrestrição. - CS0454:Dependência circular de restrições envolvendo o Parâmetro de Tipo 1 e o Parâmetro de Tipo 2.
- CS0455:O parâmetro de tipo herda restrições conflitantes.
- CS0694: O parâmetro de tipo tem o mesmo nome que o tipo ou método que contém.
-
CS0695:
Tnão pode implementar ambas as interfaces porque podem unificar-se para algumas substituições de parâmetros de tipos. - CS0698: Um tipo genérico não pode derivar do tipo porque é uma classe de atributo.
- CS0702: A restrição não pode ser de classe especial.
- CS0703: Acessibilidade inconsistente: o tipo de restrição é menos acessível do que a declaração.
- CS0706: Tipo de restrição inválido. Um tipo usado como restrição deve ser uma interface, uma classe não selada ou um parâmetro de tipo.
- CS0717: Classe estática: classes estáticas não podem ser usadas como restrições.
- CS1961: Variância inválida: O parâmetro de tipo deve ser validamente variante do tipo.
- CS7002: Uso inesperado de um nome genérico.
- CS8322: Não é possível passar argumentos com tipo dinâmico para uma função local genérica com argumentos de tipo inferido.
-
CS9011: Palavra-chave
delegatenão pode ser usada como restrição. Querias dizerSystem.Delegate? -
CS9012: Palavra-chave
recordinesperada. Queria dizerrecord structourecord class? - CS9338: Acessibilidade inconsistente: o tipo é menos acessível do que a classe.
Declaração de parâmetro de tipo e nomenclatura
Os seguintes erros relacionam-se com a forma como declara e nomeia parâmetros de tipo em tipos e métodos genéricos:
- CS0080: Não são permitidas restrições em declarações não genéricas.
- CS0081: A declaração do parâmetro de tipo deve ser um identificador, não um tipo.
- CS0412: Parâmetro: um parâmetro, variável local ou função local não pode ter o mesmo nome que um parâmetro de tipo de método.
- CS0694: O parâmetro de tipo tem o mesmo nome que o tipo ou método que contém.
-
CS9012: Palavra-chave
recordinesperada. Queria dizerrecord structourecord class?
Para corrigir estes erros, certifique-se de declarar parâmetros de tipo com identificadores válidos, aplicar cláusulas de restrição apenas a declarações genéricas e evitar conflitos de nomeação com outros identificadores no âmbito:
- Remova a cláusula de restrição de declarações não genéricas (CS0080). A
wherecláusula só pode ser usada em tipos e métodos genéricos que declaram parâmetros de tipo, porque as restrições definem requisitos que os argumentos de tipo devem satisfazer. Se você precisar aplicar restrições, primeiro adicione parâmetros de tipo à sua declaração de tipo ou método. Por exemplo, alterepublic class MyClass where MyClass : System.IDisposableparapublic class MyClass<T> where T : System.IDisposable. - Substitua nomes de tipo reais por identificadores em declarações de parâmetro de tipo (CS0081). Deve declarar parâmetros de tipo usando identificadores (como
T, , ouTKey) em vez de tipos concretos (comoTValueouintstring). O objetivo de um parâmetro de tipo é servir como um marcador que o compilador substitui por tipos reais quando o tipo ou método genérico é utilizado. Por exemplo, alterepublic void F<int>()parapublic void F<T>(). - Renomeie parâmetros de tipo, variáveis locais ou parâmetros para evitar conflitos de nomenclatura (CS0412, CS0694). Os nomes de parâmetros de tipo não podem sombrear identificadores no mesmo escopo. Eles não podem corresponder ao nome do tipo ou método que contém. Tais conflitos criam ambiguidade sobre qual identificador está sendo referenciado. Por exemplo, se você tiver um método
public void F<T>(), você não pode declarar uma variáveldouble Tlocal dentro desse método, e você não pode nomear um parâmetro de tipo o mesmo que seu tipo de contenção (class C<C>). - Use a sintaxe correta de declaração de registo (CS9012). Ao declarar um tipo de registo, deve usar ou
record classourecord struct(ou apenasrecordpara um tipo de referência). Arecordpalavra-chave sozinha não pode aparecer em posições onde o compilador espera uma sintaxe de declaração de tipo. Por exemplo, se queria declarar um tipo de registo, escrevarecord class MyRecordourecord struct MyRecordem vez de colocarrecordonde se espera uma palavra-chave diferente.
Para obter mais informações, consulte Generic Type Parameters and Generics.
Declaração de restrições e ordenação
Os seguintes erros relacionam-se com a sintaxe e ordenação das restrições em parâmetros genéricos de tipo:
-
CS0401: A
new()restrição deve ser a última restrição especificada. -
CS0449: As
classrestrições ,struct,unmanaged,notnull, edefaultnão podem ser combinadas ou duplicadas, e devem ser especificadas primeiro na lista de restrições. -
CS0450: Parâmetro de Tipo: não pode especificar ambos, uma classe de restrição e as restrições
classoustructsimultaneamente. -
CS0451: A
new()restrição não pode ser usada com astructrestrição. -
CS9011: Palavra-chave
delegatenão pode ser usada como restrição. Querias dizerSystem.Delegate?
As restrições sobre os parâmetros do tipo devem seguir uma ordem específica: as restrições primárias (class, struct, unmanaged, notnull ou default) vêm primeiro, seguidas pelas restrições de interface ou de classe e, finalmente, a restrição do construtor new(). Algumas restrições são mutuamente exclusivas e não podem ser combinadas.
Para corrigir estes erros:
- Coloque a
new()restrição no final da lista de restrições (CS0401). Anew()restrição deve aparecer após todas as outras restrições. Por exemplo, alterewhere T : new(), IDisposableparawhere T : IDisposable, new(). - Coloque as restrições primárias primeiro e não combine restrições mutuamente exclusivas (CS0449). Pode especificar no máximo um de
class,struct,unmanaged,notnull, oudefault, e deve aparecer primeiro na lista de restrições. As restriçõesclassestructsão mutuamente exclusivas, assim como o sãoclasseunmanaged. Num contexto anulável,classjá implicanotnull, por isso não podem ser combinados. - Não combines uma restrição específica de classe com
struct(CS0450). Se um parâmetro de tipo está restrito a um tipo de classe específico, é implicitamente um tipo de referência, o que contradiz astructrestrição. Remova ou a restrição de classe ou astructrestrição. - Não combines
new()comstruct(CS0451). Todos os tipos de valores (structs) têm implicitamente um construtor público sem parâmetros, pelo que anew()restrição é redundante quando combinada comstruct. Remova anew()restrição ao usarstruct. - Substitua
delegateporSystem.Delegatecláusulas de restrição (CS9011). Adelegatepalavra-chave é usada para declarar tipos de delegados, não como uma restrição. Para restringir um parâmetro de tipo a delegar tipos, useSystem.Delegatecomo tipo de restrição. Por exemplo, alterewhere T : delegateparawhere T : System.Delegate.
O exemplo seguinte mostra a ordem correta das restrições:
using System;
// Primary constraint first, then interface constraints, then new()
class C<T> where T : class, IDisposable, new() { }
// struct doesn't need new() - it's implicit
class D<T> where T : struct, IComparable { }
// Delegate constraint using System.Delegate
class E<T> where T : System.Delegate { }
Para obter mais informações, consulte Restrições em parâmetros de tipo.
Contagem e utilização de argumentos de tipo em programação
Os seguintes erros estão relacionados ao fornecimento do número e tipo corretos de argumentos de tipo para tipos e métodos genéricos:
- CS0224: Um método com vararg não pode ser genérico, ser de tipo genérico ou ter um parâmetro params.
- CS0305: Usar o tipo genérico requer argumentos do tipo N.
- CS0306: O tipo não pode ser usado como argumento de tipo.
- CS0307: O identificador não é um método genérico. Se pretendia uma lista de expressões, use parênteses à volta da expressão.
- CS0308: O tipo ou método não genérico não pode ser usado com argumentos de tipo.
- CS7002: Uso inesperado de um nome genérico.
Para corrigir esses erros, certifique-se de fornecer o número exato de argumentos de tipo exigidos pela declaração genérica. Use apenas tipos válidos como argumentos de tipo. Não aplique argumentos de tipo a construções não genéricas:
- Remova parâmetros de tipo genéricos ou que contenham declarações de tipo genéricas de métodos que usam
__arglist(CS0224). A__arglistpalavra-chave é incompatível com genéricos porque os mecanismos de tempo de execução para manipular listas de argumentos variáveis entram em conflito com a substituição de tipo necessária para parâmetros de tipo genéricos. Esta restrição também se aplica àparamspalavra-chave quando usada em combinação com métodos genéricos ou métodos dentro de tipos genéricos. - Forneça o número exato de argumentos de tipo especificados na declaração genérica de tipo ou método (CS0305). Cada parâmetro de tipo genérico declarado na definição deve ter um argumento de tipo correspondente quando o tipo genérico é instanciado. O compilador precisa saber qual tipo concreto substituir para cada parâmetro de tipo. Por exemplo, se uma classe for declarada como
class MyList<T>, você deverá fornecer exatamente um argumento de tipo ao usá-la, como , nãoMyList<int>MyList<int, string>. - Use apenas tipos válidos como argumentos de tipo (CS0306). Os tipos de ponteiro, como
int*ouchar*, não podem ser usados como argumentos de tipo porque os tipos genéricos exigem tipos gerenciados que o coletor de lixo pode rastrear e os tipos de ponteiro não são gerenciados. Se você precisar trabalhar com ponteiros em um contexto genérico, considere usarIntPtrou reestruturar seu código para evitar misturar genéricos com código inseguro. - Remova a sintaxe do argumento de tipo de construções não genéricas (CS0307, CS0308). Os argumentos de tipo entre colchetes angulares (como
<int>) só podem ser aplicados a tipos e métodos genéricos que declaram parâmetros de tipo. Você deve remover completamente os argumentos de tipo ou garantir que importou o namespace que contém a versão genérica do tipo. Por exemplo,IEnumerator<T>requer ausing System.Collections.Generic;diretiva, enquantoIEnumeratorestá emSystem.Collections. - Remover parâmetros de tipo das declarações que não suportam genéricos (CS7002). Alguns construtos, como os enums, não podem ser genéricos. Se precisares de um contêiner genérico para valores de enum, considera usar uma classe ou uma struct genérica.
Para obter mais informações, consulte Generic Type Parameters and Generics.
Restrições do construtor
Os seguintes erros estão relacionados com a restrição em parâmetros de tipo genéricos new().
-
CS0304: Não é possível criar uma instância do tipo variável porque não tem a
new()restrição. - CS0310: O tipo deve ser um tipo não abstrato com um construtor público sem parâmetros para poder ser usado como parâmetro no tipo ou método genérico.
- CS0417: Identificador: não pode fornecer argumentos ao criar uma instância de um tipo de variável.
Para corrigir esses erros, adicione a new() restrição aos parâmetros de tipo que precisam ser instanciados, certifique-se de que os argumentos de tipo tenham construtores públicos sem parâmetros e evite passar argumentos ao construir instâncias de parâmetros de tipo:
- Adicione a
new()restrição à declaração de parâmetro de tipo (CS0304). Quando você usa onewoperador para criar uma instância de um parâmetro type dentro de um tipo ou método genérico, o compilador deve ser capaz de garantir que qualquer argumento type fornecido em tempo de execução tenha um construtor sem parâmetros disponível. Anew()restrição fornece essa garantia em tempo de compilação, permitindo que o compilador gere o código de instanciação apropriado. Por exemplo, se você tiverclass C<T>com um membroT t = new T();, você deve alterar a declaração paraclass C<T> where T : new(). - Certifique-se de que os argumentos de tipo usados com
new()parâmetros de tipo restritos tenham construtores públicos sem parâmetros (CS0310). Quando um tipo ou método genérico declara umanew()restrição em um parâmetro tipo, qualquer tipo concreto usado como um argumento tipo não deve ser abstrato e deve fornecer um construtor sem argumentos público. Se um tipo tiver apenas construtores não públicos (comoprivateconstrutores ouprotectedconstrutores) ou só tiver construtores com parâmetros, não pode satisfazer anew()restrição. Para corrigir este erro, pode adicionar um construtor público sem parâmetros ao tipo ou usar um argumento de tipo diferente que já tenha um. - Remova os argumentos do construtor ao instanciar parâmetros de tipo (CS0417). A
new()restrição apenas garante a existência de um construtor sem parâmetros, por isso não pode passar argumentos anew T(arguments)porque o compilador não pode verificar que existe um construtor com esses tipos específicos de parâmetros nos tipos que substituem porT. Se precisares de construir instâncias com argumentos específicos, considera usar métodos de fábrica, padrões abstratos de fábrica, ou restrições específicas de classe base ou interface que definam o comportamento de construção de que precisas.
Para mais informações, veja Restrições nos parâmetros de tipo e na new() restrição.
Satisfação de restrições e conversões
Os seguintes erros estão relacionados a argumentos de tipo que não satisfazem as restrições de parâmetros de tipo genéricos:
-
CS0311:O tipo não pode ser usado como parâmetro
Tde tipo no tipo genérico ou método. Não existe conversão implícita de referências. - CS0312: O tipo não pode ser usado como parâmetro de tipo no tipo genérico ou método. O tipo nulo não satisfaz a restrição.
- CS0313: O tipo não pode ser usado como parâmetro de tipo no tipo genérico ou método. O tipo nulo não satisfaz a restrição. Tipos anuláveis não conseguem satisfazer quaisquer restrições de interface.
- CS0314: O tipo não pode ser usado como parâmetro de tipo no tipo genérico ou método. Não existe conversão para boxing nem conversão de parâmetros de tipo.
-
CS0315: O tipo não pode ser usado como parâmetro
Tde tipo no tipo genérico ou métodoTypeorMethod<T>. Não há conversão para boxe.
Para corrigir esses erros, use argumentos de tipo que satisfaçam todas as restrições por meio de conversões apropriadas, certifique-se de que as classes derivadas repitam as restrições de classe base e entenda que os tipos de valor nulo têm requisitos de restrição especiais:
- Altere o argumento type para um que tenha uma conversão de referência implícita para o tipo de restrição (CS0311). Quando um parâmetro de tipo tem uma restrição como
where T : BaseType, qualquer argumento de tipo deve ser convertível emBaseTypepor meio de uma conversão de referência implícita ou conversão de identidade. O argumento do tipo deve serBaseTypeele próprio, derivar deBaseType, ou implementarBaseTypese for uma interface. Conversões numéricas implícitas (como deshortparaint) não satisfazem restrições genéricas de parâmetros de tipo porque essas conversões são de valor, não de referência. - Repita as restrições de parâmetro de tipo da classe base em qualquer declaração de classe derivada (CS0314). Quando uma classe genérica derivada herda de uma classe genérica base que tem restrições em seus parâmetros de tipo, a classe derivada deve declarar as mesmas restrições em seus parâmetros de tipo correspondentes. Deve repetir estas restrições porque o compilador precisa de verificar que os argumentos de tipo fornecidos à classe derivada satisfaz os requisitos da classe base. Por exemplo, se você tiver
public class A<T> where T : SomeClass, então qualquer classe derivada dele deve ser declarada comopublic class B<T> : A<T> where T : SomeClass. - Use tipos de valor não anuláveis ou altere o tipo de restrição (CS0312, CS0313). Os tipos de valor anulável (como
int?) são distintos de seus tipos de valor subjacentes e não satisfazem as mesmas restrições. Não há conversão implícita entreint?eint, e os tipos de valor anulável não podem satisfazer as restrições de interface porque o wrapper anulável em si não implementa a interface, mesmo que o tipo de valor subjacente o faça. Para corrigir esses erros, use a forma não anulável do tipo de valor como o argumento type ou ajuste sua restrição para aceitarobjectou um tipo de referência anulável, se apropriado. - Certifique-se de que os argumentos de tipo satisfaçam as restrições de tipo ou classe de referência (CS0315). Quando um parâmetro de tipo é restrito a um tipo de classe (como
where T : SomeClass), não se pode usar um tipo de valor (struct) como argumento de tipo porque não há conversão de encaixotamento que satisfaça a relação de restrição. A restrição requer um tipo de referência que tenha uma relação de herança ou implementação com o tipo de restrição. Para resolver esse erro, altere o struct para uma classe, se semanticamente apropriado, ou remova a restrição de classe se o tipo genérico puder trabalhar com tipos de valor.
Para obter mais informações, consulte Restrições em parâmetros de tipo e Conversões implícitas.
Restrições de uso de tipo genérico
Os seguintes erros referem-se a restrições sobre a forma como os tipos genéricos podem ser utilizados:
-
CS0403: Não é possível converter nulo em parâmetro de tipo porque pode ser um tipo de valor não anulável. Considera usar
default(T)em vez disso. -
CS0413: O parâmetro de tipo não pode ser usado com o
asoperador porque não tem uma restrição de tipo de classe nem umaclassrestrição. - CS0695: O tipo não pode implementar ambas as interfaces porque elas podem se unificar em algumas substituições de parâmetros de tipo.
- CS0698: Um tipo genérico não pode derivar do tipo porque é uma classe de atributo.
- CS8322: Não é possível passar argumentos com tipo dinâmico para uma função local genérica com argumentos de tipo inferido.
- CS9338: Acessibilidade inconsistente: o tipo é menos acessível do que a classe.
Para corrigir esses erros, use default em vez de parâmetros de tipo sem restrições, adicione restrições de null classe ao usar o as operador, evite conflitos de unificação de interface, não crie classes de atributos genéricas e garanta que os argumentos de tipo correspondam à visibilidade de seus membros que os contêm:
- Substituir
nullas atribuições pordefault(T)ou adicionar umaclassrestrição (CS0403). Quando você atribuinulla um parâmetro de tipo sem restrições, o compilador não pode garantir que o argumento type seja um tipo de referência que aceitenullvalores, porque pode ser um tipo de valor comointoustruct, que não pode sernull. Para resolver esse erro, usedefault(T), que fornece o valor padrão apropriado para qualquer tipo (nulo para tipos de referência, zero ou vazio para tipos de valor) ou adicione umaclassrestrição ao parâmetro type se precisar especificamente de semântica de tipo de referência e quiser permitirnullatribuições. - Adicione uma restrição de
classtipo ou específica ao usar oasoperador (CS0413). Oasoperador executa uma conversão de tipo segura que retornanullse a conversão falhar, mas esse comportamento é incompatível com tipos de valor porque os tipos de valor não podem sernull. Quando você usaascom um parâmetro de tipo sem restrições, o compilador não pode garantir que o argumento type não seja um tipo de valor, portanto, ele rejeita o código. Para corrigir esse erro, adicione umaclassrestrição ou uma restrição de tipo de referência específica (comowhere T : SomeClass) para garantir que o parâmetro type seja sempre um tipo de referência que possa manipular corretamente onullresultado de uma conversão com falha. - Evite implementar a mesma interface genérica várias vezes com parâmetros de tipo que poderiam unificar (CS0695). Quando uma classe implementa uma interface genérica várias vezes com parâmetros de tipo diferentes (como
class G<T1, T2> : I<T1>, I<T2>), há um risco de que alguém possa instanciá-la com o mesmo tipo para ambos os parâmetros (G<int, int>), o que criaria um conflito porque a classe estaria efetivamente implementandoI<int>duas vezes. Para resolver esse erro, implemente a interface apenas uma vez, reestruture seus parâmetros de tipo para evitar a unificação ou use classes não genéricas separadas para especializações diferentes. - Remova parâmetros de tipo genéricos de classes de atributo (CS0698).
Observação
Este erro não é produzido nas versões atuais do C#, pois atributos genéricos são agora suportados.
- Especifique explicitamente argumentos de tipo ao passar valores dinâmicos para funções locais genéricas (CS8322). Quando passa um
dynamicargumento para uma função local genérica, o compilador não pode inferir argumentos de tipo porque o tipo real só é conhecido em tempo de execução. Para corrigir este erro, especifique explicitamente o argumento do tipo (por exemplo,LocalFunc<int>(d)), conjure o valor dinâmico para o tipo esperado, ou use uma variável não dinâmica. - Verifique se os argumentos de tipo usados em assinaturas públicas ou protegidas são pelo menos tão acessíveis quanto o membro que os usa (CS9338). Um membro público ou genérico protegido deve usar argumentos de tipo que sejam acessíveis publicamente. Caso contrário, o código externo não poderia referenciar ou usar corretamente a assinatura do membro. Por exemplo, se tiver
public class Container<T>ondeTé um tipo interno, os assemblies externos podem ver oContainer, mas não conseguem trabalhar corretamente com ele porque não conseguem verT. Para corrigir esse erro, torne o argumento type público ou reduza a acessibilidade do membro que o usa para corresponder à acessibilidade do argumento type.
Para obter mais informações, consulte Restrições em parâmetros de tipo, expressões de valor padrão e Atributos.
Tipos de restrições válidos
Os seguintes erros relacionam-se com o uso de tipos inválidos como restrições em parâmetros genéricos de tipo:
- CS0405: Restrição duplicada para o parâmetro de tipo.
- CS0702: A restrição não pode ser de classe especial.
- CS0703: Acessibilidade inconsistente: o tipo de restrição é menos acessível do que a declaração.
- CS0706: Tipo de restrição inválido. Um tipo usado como restrição deve ser uma interface, uma classe não selada ou um parâmetro de tipo.
-
CS0717:
static class: classes estáticas não podem ser usadas como restrições.
Uma restrição deve ser uma interface, uma classe não selada ou um parâmetro de tipo. Certos tipos são inválidos como restrições devido ao seu significado especial no sistema de tipos .NET ou porque não podem ser herdados.
Para corrigir estes erros:
- Remover restrições duplicadas (CS0405). Cada restrição só pode aparecer uma vez numa cláusula de restrição. Se tiver
where T : I, I, remove o duplicado. - Não uses classes especiais como restrições (CS0702). Os tipos Object, Array, e ValueType não podem ser usados como restrições. Todo tipo já deriva de
Object, por isso restringir-se a ele não fornece valor.ArrayeValueTypesão tipos base abstratos que não podem ser herdados diretamente. Se precisares de comportamento semelhante a um array, usaIList<T>ouIEnumerable<T>em vez disso. - Garantir que os tipos de restrições são pelo menos tão acessíveis quanto o tipo genérico (CS0703). Um tipo genérico público não pode ter restrições usando tipos internos, porque código externo não conseguiria fornecer argumentos de tipo válidos. Ou torna o tipo de restrição público, ou reduz a acessibilidade do tipo genérico.
- Use apenas interfaces, classes não seladas ou parâmetros de tipo como restrições (CS0706). Não podes usar arrays, classes seladas, structs, enums ou outros tipos inválidos como restrições. Se precisar de comportamentos específicos, considere usar uma interface que os tipos desejados implementem.
- Não uses classes estáticas como restrições (CS0717). As classes estáticas não podem ser estendidas porque só contêm membros estáticos. Nenhum tipo pode existir que derive de uma classe estática, tornando-o inútil como restrição. Use antes uma classe ou interface não estática.
O exemplo seguinte mostra tipos de restrições válidos:
public interface IMyInterface { }
public class MyBaseClass { }
// Valid: interface constraint
class A<T> where T : IMyInterface { }
// Valid: non-sealed class constraint
class B<T> where T : MyBaseClass { }
// Valid: type parameter constraint
class C<T, U> where T : U { }
Para obter mais informações, consulte Restrições em parâmetros de tipo.
Conflitos de restrições e dependências circulares
Os seguintes erros relacionam-se com conflitos entre restrições ou dependências circulares em declarações de restrições:
- CS0454:Dependência circular de restrições envolvendo o Parâmetro de Tipo 1 e o Parâmetro de Tipo 2.
- CS0455:O parâmetro de tipo herda restrições conflitantes.
As restrições não podem criar dependências circulares, e os parâmetros de tipo não podem herdar restrições conflitantes que são impossíveis de satisfazer simultaneamente.
Para corrigir estes erros:
- Remover dependências circulares de restrições (CS0454). Um parâmetro de tipo não pode depender direta ou indiretamente de si próprio através das suas restrições. Por exemplo,
where T : U where U : Tcria uma dependência circular porqueTdepende deUeUdepende deT. Quebra o ciclo removendo uma das restrições. - Remover restrições herdadas conflitantes (CS0455). Um parâmetro de tipo não pode ser limitado a múltiplas classes não relacionadas, porque C# não suporta herança múltipla de classes. De forma semelhante, não pode ser restringido a ambos
structe a um tipo de classe, pois estas restrições são mutuamente exclusivas. Reestrutura a hierarquia de tipos ou remove uma das restrições conflitantes.
O exemplo seguinte mostra os problemas:
// CS0454: Circular dependency - T depends on U and U depends on T
class Circular<T, U> where T : U where U : T { }
// CS0455: Conflicting constraints - U can't derive from both B and B2
public class B { }
public class B2 { }
public class G<T> where T : B
{
public class N<U> where U : B2, T { }
}
Para obter mais informações, consulte Restrições em parâmetros de tipo.
Variância do parâmetro de tipo
O seguinte erro relaciona-se com modificadores de variância em parâmetros genéricos de tipo:
- CS1961: Variância inválida: O parâmetro de tipo deve ser validamente variante do tipo.
Modificadores de variância (in para contravariância, out para covariância) controlam como usas os parâmetros de tipo na interface e delegam declarações. Um parâmetro de tipo covariante (out) só pode aparecer em posições de saída (tipos de retorno), enquanto um parâmetro de tipo contravariante (in) só pode aparecer em posições de entrada (tipos de parâmetro).
Para corrigir este erro:
- Use
out(covariante) para parâmetros de tipo que só aparecem nos tipos de retorno. A covariância permite usar um tipo mais derivado onde se espera um tipo menos derivado. - Use
in(contravariante) para parâmetros de tipo que só aparecem nos tipos de parâmetros. A contravariância permite usar um tipo menos derivado onde se espera um tipo mais derivado. - Remova o modificador de variância se o parâmetro de tipo tiver de aparecer tanto nas posições de entrada como de saída.
O exemplo seguinte mostra o uso correto e incorreto da variância:
// Incorrect: out T can't appear in input position
interface IWrong<out T>
{
void Method(T arg); // CS1961
}
// Correct: out T only in output positions
interface ICovariant<out T>
{
T GetValue();
}
// Correct: in T only in input positions
interface IContravariant<in T>
{
void Process(T arg);
}
// No modifier needed for both input and output
interface IInvariant<T>
{
T Transform(T arg);
}
Para mais informações, veja Covariância e Contravariância em Genéricos.