Código
Significado
O que fazer
EQ2001
Um construto C# sem equivalente em runtime no browser (intrínsecos de typed reference: __makeref, __reftype, __refvalue, stackalloc, ponteiros).
Reestruture sem ele.
EQ2002
goto.
Reestruture com laços e condicionais, ou um break/continue rotulado (esses TRADUZEM).
EQ2003
new T() sobre parâmetro de tipo — argumentos genéricos são apagados em runtime no JavaScript, então o tipo concreto é desconhecido.
Passe uma fábrica (Func<T>) ou o valor já construído.
EQ2004
Um membro sem tradução para JavaScript: um método de extensão cuja classe declarante não faz parte desta compilação, ou uma chamada que o transpilador não mapeia (Stopwatch.StartNew, Roslyn…) dentro de uma classe que ele espelha, escrita qualificada ou alcançada pelo nome simples por um using static (WriteLine sob using static System.Console, desde 0.2.0-preview.60). Também um valor System.Range guardado em vez de usado como índice, ou passado a um indexador que recebe o próprio Range (this[Range r], desde 0.2.0-preview.61).
Use um membro de instância ou traga o fonte declarante; adicione uma estratégia; para um intervalo, indexe com ele diretamente (text[a..b]), ou dê ao tipo um Length (ou um Count) e um Slice(int start, int length), que um intervalo chama; mova a chamada para trás de um [ServerAction]; ou, quando a classe inteira só roda no servidor, marque a CLASSE com [ServerOnly] e nenhum módulo é emitido para ela (0.2.0-preview.46).
EQ2005
Um iterador infinito. Iteradores são MATERIALIZADOS num array, então o laço rodaria para sempre em vez de render preguiçosamente.
Dê um fim ao laço (um limite, um yield break), ou consuma o que precisa dentro do método.
EQ2006
O membro não vincula no modelo semântico, então qualquer tradução seria palpite.
Ou o código não compila, ou faltam referências / fontes gerados ao eqc. Nunca é adivinhado — veja Compilador. EQ2007
Um comparador que muda o que uma coleção considera igual ou em ordem: um argumento with(…) de collection expression além da dica de capacidade, ou um comparador passado ao construtor de uma coleção (new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase)) ou a um operador LINQ que acha as suas chaves ou os seus elementos por ele (ToHashSet, e ToDictionary, ToLookup, GroupBy e Distinct desde 0.2.0-preview.61). Uma lista, um set ou um dicionário acha um elemento pela igualdade padrão do seu tipo e não aceita outra: os comparadores padrão e o StringComparer.Ordinal passam. Uma ordenação ou uma busca binária aceita o comparador padrão do tipo, um Comparison<T>, os seis do StringComparer, Comparer<T>.Create e um comparador que você escreve, e recusa só um que nenhum twin carrega (um StringComparer feito para uma cultura, um comparador que uma biblioteca compilou).
Remova o comparador, ou normalize as chaves você mesmo (em minúsculas na entrada e em cada busca). Para uma ordenação, passe um Comparison<T>.
EQ2008
Query syntax com join, let, um segundo from ou into — a tradução em C# passa por identificadores transparentes gerados pelo compilador. Também as formas cercadas de inicializador.
Reescreva em method syntax, onde todo operador é suportado.
EQ2009
Um componente declarado mais de uma vez num arquivo (declarações parciais). O eqc emite um módulo por declaração e não sabe fundi-las.
Junte os membros numa declaração só.
EQ2010
Um símbolo que o framework mantém no HOST — um tipo ou um único membro marcado [ServerOnly] — nomeado a partir de código do cliente. O runtime não traz gêmeo, portanto a referência compilaria, seria emitida e falharia na hidratação com "does not provide an export named", enquanto o SSR continuava a responder 200. Um método de extensão chamado sobre um valor que atravessa também nomeia a casa dele: curve.Ease(t) é CurveEvaluator.Ease(curve, t), e falhava na chamada. Um tipo declarado dentro de um que nunca atravessa (uma classe [ServerOnly] ou um atributo) também não tem gêmeo, como o dono não tem, enquanto um declarado dentro de uma classe de exceção da app atravessa como essa classe, então código do cliente que o alcança é recusado da mesma forma, seja como for que o alcance: pelo nome, por um alias, por using static, por um operador ou uma conversão que o seu valor traz, ou por um zero. Um módulo que importaria o seu gêmeo o reporta na declaração que guarda a referência (Desde 0.2.0-preview.61). Um membro marcado [ServerOnly] é recusado onde quer que código do cliente o nomeie, inclusive o código do próprio tipo: um componente deixa um método assim fora do gêmeo, e o Build dele chamando-o era uma chamada a um membro que o gêmeo não tem (Desde 0.2.0-preview.62).
Chame-o de código de servidor: um [ServerAction], uma classe [ServerOnly] ou um realizador. Nunca do Build de um componente. Ao contrário do EQ2004, isto é uma DECISÃO e não uma lacuna — acrescentar uma estratégia não é a resposta.
EQ2011
Um membro que tomaria um nome que o componente do runtime já usa. O C# mantém separados um parâmetro de construtor primário, um campo e uma propriedade, e os escreve diferente do camelCase do runtime; o JavaScript dobra tudo isso em this.<nome>, então a atribuição substitui o membro do runtime e a página falha só no browser. A lista é lida do runtime vivo, nunca digitada.
Renomeie o membro. Um override é isento — o Build de um componente existe para substituir o build do runtime, e substituir membro de base é para isso que serve — mas um método comum não é: public void Mount() { } não sobrescreve nada e mesmo assim emite mount() por cima do do runtime, então o componente nunca monta.
EQ2012
Um [ServerAction] num componente ABSTRATO. O servidor registra uma ação sob o nome do componente CONCRETO que a carrega — ele pula os tipos abstratos e percorre os métodos herdados — então serve Tile/Load enquanto um stub emitido na base invocaria CardBase/Load. Nada serve esse id e a página recebe "action not found", em silêncio dos dois lados.
Declare a ação no componente concreto. Um alias não resolve: o descritor carrega o TIPO do componente em que invocar, então duas filhas herdando uma ação dão duas respostas ao id da base — quem é dono de uma ação herdada é uma decisão, não um remendo.
EQ2013
Um tipo do vocabulário cuja metade no browser revive os valores de um argumento de tipo (ServerTopic<T>) é construído onde esse argumento é, ou contém, um parâmetro de tipo, como em static ServerTopic<T> Topic<T>(string name) => new(name). O JavaScript apaga o tipo ali, então o tópico não levaria spec e todo payload chegaria aos assinantes sem ser revivido: um decimal ou um long como o texto que o fio escreve, um record sem os seus membros.
Construa o tópico onde o tipo do payload é concreto, como um membro estático do tipo que declara os tópicos do app: static ServerTopic<RoomEvent> Room(string id) => new($"room:{id}"). Veja Eventos do servidor. EQ2014
Um tipo de exceção é construído ou testado onde um argumento de tipo que ele carrega, o seu ou o de um tipo em que está aninhado, é, ou contém, um parâmetro de tipo, como em static Exception Of<T>() => new Failed<T>(), catch (Failed<T>), ou new Missing() dentro da classe genérica que a declara. Uma exceção carrega os tipos que é, que um catch tipado, um is e o seu nome leem, e o JavaScript apaga um parâmetro de tipo, então a exceção carregaria, ou o teste compararia, o próprio T: catch (Failed<int>) não pegava o que Of<int>() lançava (Desde 0.2.0-preview.61).
Construa e teste uma exceção onde os seus argumentos de tipo são tipos concretos, e declare uma classe de exceção fora de um tipo genérico.