Diagnosticar erros de componente do C#/WinRT

Este artigo fornece informações adicionais sobre restrições em Componentes do Windows Runtime escritos com C#/WinRT. Ele expande as informações fornecidas em mensagens de erro do C#/WinRT quando um autor cria o componente. Para componentes gerenciados .NET Native da UWP existentes, os metadados para componentes C#WinRT são gerados usando Winmdexp.exe, uma ferramenta do .NET. Agora que o suporte ao Windows Runtime é desacoplado do .NET, o C#/WinRT fornece as ferramentas para gerar um arquivo .winmd do componente. O Windows Runtime tem mais restrições no código do que uma biblioteca de classes C#, e o Scanner de Diagnóstico do C#/WinRT alerta você sobre eles antes de gerar um arquivo .winmd.

Este artigo aborda os erros relatados no build do C#/WinRT. Este artigo serve como uma versão atualizada das informações sobre restrições para componentes gerenciados .NET Native da UWP existentes que usam a ferramenta Winmdexp.exe.

Pesquise o texto da mensagem de erro (omitindo valores específicos de espaços reservados) ou o número da mensagem. Caso você não encontre as informações de que precisa aqui, ajude-nos a melhorar a documentação usando o botão de comentários ao final deste artigo. Inclua a mensagem de erro nos seus comentários. Como alternativa, você pode registrar um bug no repositório do C#/WinRT.

Este artigo organiza mensagens de erro por cenário.

Implementando interfaces que não são válidas no Windows Runtime

Os componentes do C#/WinRT não podem implementar certas interfaces do Windows Runtime, como as interfaces do Windows Runtime que representam ações ou operações assíncronas (IAsyncAction, IAsyncActionWithProgress<TProgress>, IAsyncOperation<TResult> ou IAsyncOperationWithProgress<TResult, TProgress>). Em vez disso,use a classe AsyncInfo para gerar operações assíncronas em componentes do Windows Runtime. Observação: essas não são as únicas interfaces inválidas, por exemplo, uma classe não pode implementar System.Exception.

Número do erro

Texto da mensagem

CsWinRT1008

O componente do Windows Runtime do tipo {0} não pode implementar a interface {1}, pois ela não é uma interface válida do Windows Runtime

No Windows Runtime, os métodos sobrecarregados só podem ter o mesmo número de parâmetros caso uma sobrecarga seja especificada como a sobrecarga padrão. Use o atributo Windows.Foundation.Metadata.DefaultOverload (CsWinRT1015, 1016).

Quando as matrizes são usadas como entradas ou saídas em funções ou propriedades, elas precisam ser somente leitura ou somente gravação (CsWinRT 1025). Os atributos System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArray e System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArray são fornecidos para o seu uso. Os atributos fornecidos são apenas para uso em parâmetros do tipo de matriz (CsWinRT1026), e somente um deve ser aplicado por parâmetro (CsWinRT1023).

Não é necessário aplicar um atributo para um parâmetro de matriz marcado como saída, pois supõe-se que ele seja somente gravação. Há uma mensagem de erro se você o decorar como somente leitura nesse caso (CsWinRT1024).

Os atributos System.Runtime.InteropServices.InAttribute e System.Runtime.InteropServices.OutAttribute não devem ser usados em parâmetros de qualquer tipo (CsWinRT1021,1022).

Número do erro

Texto da mensagem

CsWinRT1015

Na classe {2}: Várias sobrecargas de parâmetros {0} de {1} são decoradas com Windows.Foundation.Metadata.DefaultOverloadAttribute. O atributo só pode ser aplicado a uma sobrecarga do método.

CsWinRT1016

Na classe {2}: As sobrecargas de parâmetros {0} de {1} precisam ter exatamente um método especificado como a sobrecarga padrão decorando-a com o atributo Windows.Foundation.Metadata.DefaultOverloadAttribute.

CsWinRT1021

O método '{0}' tem um parâmetro '{1}' que é uma matriz e que tem System.Runtime.InteropServices.InAttribute ou System.Runtime.InteropServices.OutAttribute. No Windows Runtime, os parâmetros de matriz precisam ter ReadOnlyArray ou WriteOnlyArray. Remova esses atributos ou os substitua pelo atributo de Tempo de Execução do Windows apropriado, se necessário.

CsWinRT1022

O método '{0}' tem o parâmetro '{1}' com um System.Runtime.InteropServices.InAttribute ou o System.Runtime.InteropServices.OutAttribute.Windows Runtime não dá suporte a marcar os parâmetros com System.Runtime.InteropServices.InAttribute ou System.Runtime.InteropServices.OutAttribute. Leve em consideração a remoção de System.Runtime.InteropServices.InAttribute e substitua System.Runtime.InteropServices.OutAttribute pelo modificador 'out' em vez disso.

CsWinRT1023

O método '{0}' tem um parâmetro '{1}' que é uma matriz e que tem ReadOnlyArray e WriteOnlyArray. No Tempo de Execução do Windows, os parâmetros de matriz de conteúdo devem ser legíveis ou graváveis. Remova um dos atributos de '{1}'.

CsWinRT1024

O método '{0}' tem um parâmetro de saída '{1}' que é uma matriz, mas que tem o atributo ReadOnlyArray. No Tempo de Execução do Windows, o conteúdo das matrizes de saída é gravável. Remova o atributo de '{1}'.

CsWinRT1025

O método '{0}' tem um parâmetro '{1}', que é uma matriz. No Tempo de Execução do Windows, o conteúdo dos parâmetros de matriz deve ser legível ou gravável. Aplique ReadOnlyArray ou WriteOnlyArray a '{1}'.

CsWinRT1026

O método '{0}' tem o parâmetro '{1}', que não é uma matriz e que tem um atributo ReadOnlyArray ou um atributo WriteOnlyArray. O Windows Runtime não dá suporte à marcação de parâmetros que não são de matriz com ReadOnlyArray ou WriteOnlyArray. "

Erros de namespace e nomes inválidos para o arquivo de saída

No Windows Runtime, todos os tipos públicos em um arquivo de metadados do Windows (.winmd) precisam estar um namespace que compartilhe o nome de arquivo .winmd ou em subnamespaces do nome de arquivo. Por exemplo, caso o projeto do Visual Studio se chame A.B (ou seja, o componente do Windows Runtime é A.B.winmd), ele pode conter classes públicas A.B.Class1 e A.B.C.Class2, mas não A.Class3 ou D.Class4.

Observação

Essas limitações se aplicam somente aos tipos públicos, não aos tipos privados usados em sua implementação.

No caso de A.Class3, é possível mover Class3 para outro namespace ou alterar o nome do componente do Windows Runtime para A.winmd. No exemplo anterior, o código que chama A.B.winmd não conseguirá localizar A.Class3.

No caso de D.Class4, nenhum nome de arquivo pode conter ambas D.Class4 e as classes no namespace A.B, logo, alterar o nome do componente do Windows Runtime não é uma opção. Você pode mover D.Class4 para outro namespace ou colocá-la em outro componente do Windows Runtime.

O sistema de arquivos não consegue diferenciar maiúsculas e minúsculas, logo, namespaces que diferenciam entre maiúsculas e minúsculas não são permitidos (CsWinRT1002).

Número do erro

Texto da mensagem

CsWinRT1001

Um tipo público tem um namespace ('{1}') que não compartilha um prefixo em comum com outros namespaces ('{0}'). Todos os tipos dentro de um arquivo de metadados do Windows devem estar em um subnamespace do namespace implícito do nome do arquivo.

CsWinRT1002

Vários namespaces encontrados com o nome '{0}'; os nomes de namespace não podem diferir somente por maiúsculas e minúsculas no Windows Runtime.

{1>{2>Exportando tipos que não são tipos válidos do Tempo de Execução do Windows<2}<1}

A interface pública do componente precisa expor somente tipos do Windows Runtime. No entanto, o .NET fornece mapeamentos para vários tipos comumente usados que são ligeiramente diferentes no .NET e no Windows Runtime. Isso permite que o desenvolvedor do .NET trabalhe com tipos familiares, em vez de aprender novos. É possível usar esses tipos do .NET Framework mapeados na interface pública do componente. Para obter mais informações, confira Declarando tipos em Componentes do Windows Runtime, Passando tipos do Windows Runtime para código gerenciado e Mapeamentos .NET de tipos do Windows Runtime.

Muitos desses mapeamentos são interfaces. Por exemplo, o IListT<T> é mapeado para a o IVector<T> da interface do Windows Runtime. Caso você use List<string> em vez de IList<string> como tipo de parâmetro, o C#/WinRT oferece uma lista de alternativas que inclui todas as interfaces mapeadas implementadas por List<T>. Se você usar tipos genéricos aninhados, como List<Dictionary<int, string>>, o C#/WinRT oferecerá opções para cada nível de aninhamento. Essas listas podem ficar muito longas.

Em geral, a melhor opção é a interface mais próxima do tipo. Por exemplo, para Dictionary<int, string>, a melhor opção é mais provavelmente IDictionary<int, string>.

Número do erro

Texto da mensagem

CsWinRT1006

O membro '{0}' tem o tipo '{1}' na assinatura dele. O tipo'{1}' não é um tipo válido do Windows Runtime. Ainda assim, o tipo (ou os parâmetros genéricos) implementa interfaces que são tipos válidos do Windows Runtime. Considere alterar o tipo '{1} na assinatura de membro para um dos tipos a seguir de System.Collections.Generic: {2}.

No Windows Runtime, as matrizes em assinaturas de membro precisam ser unidimensionais com um limite inferior de 0 (zero). Tipos de matriz aninhada como myArray[][] (CsWinRT1017) e myArray[,] (CsWinRT1018) não são permitidos.

Observação

Essa limitação não se aplica a matrizes que você usa internamente em sua implementação.

Número do erro

Texto da mensagem

CsWinRT1017

O método {0} tem uma matriz aninhada do tipo {1} na assinatura. As matrizes em assinaturas do método do Windows Runtime não podem ser aninhadas.

CsWinRT1018

O método '{0}' tem uma matriz multidimensional do tipo '{1}' na assinatura. As matrizes em assinaturas do método de Tempo de Execução do Windows devem ser unidimensionais.

Estruturas que contêm campos de tipos não permitidos

No Windows Runtime, uma estrutura só pode conter somente campos e somente estruturas podem conter campos. Esses campos devem ser públicos. Entre os tipos de campo válidos estão enumerações, estruturas e tipos primitivos.

Número do erro

Texto da mensagem

CsWinRT1007

A estrutura {0} não contém campos públicos. As estruturas do Windows Runtime precisam conter pelo menos um campo público.

CsWinRT1011

A estrutura {0} tem um campo não público. Todos os campos precisam ser públicos para estruturas do Windows Runtime.

CsWinRT1012

A estrutura {0} tem um campo const. As constantes só podem aparecer em enumerações do Windows Runtime.

CsWinRT1013

A estrutura {0} tem o campo do tipo {1}; {1} não é um tipo de campo válido do Windows Runtime. Cada campo em uma estrutura de Tempo de Execução do Windows só pode ser UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, ou a própria estrutura.

O nome do parâmetro está em conflito com o código gerado

No Windows Runtime, os valores de retorno são considerados parâmetros de saída e os nomes dos parâmetros precisam ser exclusivos. Por padrão, o C#/WinRT fornece ao valor retornado o nome __retval. Se o método tiver um parâmetro chamado __retval, você receberá o erro CsWinRT1010. Para corrigir isso, dê ao parâmetro um nome diferente de __retvalue.

Número do erro

Texto da mensagem

CsWinRT1010

O nome do parâmetro {1} no método {0} é o mesmo que o nome do parâmetro de valor retornado usado na interop C#/WinRT gerada; use um nome de parâmetro diferente.

Diversos

Outras restrições em um componente de criação de C#/WinRT de incluem:

  • Não é possível expor operadores sobrecarregados em tipos públicos.
  • As classes e interfaces não podem ser genéricas.
  • As classes precisam ser seladas.
  • Os parâmetros não podem ser passados por referência, por exemplo, usando a palavra-chave referência.
  • As propriedades precisam ter um método get público.
  • Precisa haver pelo menos um tipo público (classe ou interface) no namespace do componente.

Número do erro

Texto da mensagem

CsWinRT1014

'{0}' é uma sobrecarga de operador. Os tipos gerenciados não podem expor sobrecargas do operador no Tempo de Execução do Windows.

CsWinRT1004

O tipo {0} é genérico. Os tipos do Windows Runtime não podem ser genéricos.

CsWinRT1005

Não há suporte para a exportação de tipos não selados no CsWinRT. Marque o tipo {0} como selado.

CsWinRT1020

O método '{0}' tem o parâmetro '{1}' marcado como `ref`. Os parâmetros de referência não são permitidos no Windows Runtime.

CsWinRT1000

A propriedade '{0}' não tem um método getter público. O Windows Runtime não dá suporte a propriedades somente setter.

CsWinRT1003

Os componentes do Windows Runtime precisam ter pelo menos um tipo público

No Windows Runtime, uma classe pode ter apenas um construtor com um determinado número de parâmetros. Por exemplo, você não pode ter um construtor que tem um único parâmetro do tipo cadeia de caracteres e outro construtor que tem um único parâmetro do tipo int. A única solução alternativa é usar um número diferente de parâmetros para cada construtor.

Número do erro

Texto da mensagem

CsWinRT1009

As classes não podem ter vários construtores do mesmo arity no Windows Runtime, a classe {0} tem vários construtores {1}-arity.