Pergunta

Existem boas soluções para representar um enum parametrizado em C# 3.0?Estou procurando algo como OCaml ou Haxe tem.Só consigo pensar em hierarquia de classes com um campo enum simples para facilitar a troca por enquanto, talvez haja ideias melhores?

Veja o exemplo Ocaml abaixo em uma das respostas, segue um código Haxe:

enum Tree {
   Node(left: Tree, right: Tree);
   Leaf(val: Int);
}
Foi útil?

Solução

Não estando familiarizado com OCaml ou Haxe, e não sendo inteligente o suficiente para entender as outras explicações, fui procurar o Documentação Haxe enum - o bit 'Enum Type Parameters' na parte inferior parece ser a parte relevante.

Meu entendimento com base nisso é o seguinte:

Um enum 'normal' é basicamente um valor restrito às coisas que você definiu em sua definição de enum.Exemplo C#:

enum Color{ Red, Green, Yellow, Blue };
Color c = Color.Red;

c pode ser Red, Green, Yellow, ou Blue, mas nada mais.

No Haxe, você pode adicionar tipos complexos a enums, exemplo inventado de sua página:

enum Cell<T>{ 
  empty; 
  cons( item : T, next : Cell<T> )
}

Cell<int> c = <I don't know>;

O que isso parece quer dizer é que c está restrito a ser o valor literal empty (como nossos antigos enums C#), ou também pode ser um tipo complexo cons(item, next), onde item é um T e next é um Cell<T>.

Como nunca usei isso, parece que provavelmente está gerando alguns tipos anônimos (como o compilador C# faz quando você faz new { Name='Joe'}.
Sempre que você 'acessar' o valor enum, você deve declarar item e next quando você faz isso, parece que eles ficam vinculados a variáveis ​​locais temporárias.

Exemplo Haxe - Você pode ver 'next' sendo usado como uma variável local temporária para extrair dados da estrutura anônima de cons:

switch( c ) {
  case empty : 0;
  case cons(item,next): 1 + cell_length(next);
}

Para ser honesto, isso me surpreendeu quando “cliquei” no que parecia estar fazendo.Parece incrivelmente poderoso e posso ver por que você estaria procurando um recurso semelhante em C#.

As enumerações C# são praticamente iguais às enumerações C/++ das quais foram originalmente copiadas.É basicamente uma maneira legal de dizer #define Red 1 para que o compilador possa fazer comparações e armazenamento com números inteiros em vez de strings quando você estiver passando Color objetos ao redor.

Minha tentativa de fazer isso em C# seria usar genéricos e interfaces.Algo assim:

public interface ICell<T> {
   T Item{ get; set; }
   ICell<T>{ get; set; }
}

class Cons<T> : ICell<T> {
  public T Item{ get; set; } /* C#3 auto-backed property */
  public Cell<T> Next{ get; set; }
}

class EmptyCell<T> : ICell<T>{
  public T Item{ get{ return default(T); set{ /* do nothing */ }; }
  public ICell<T> Next{ get{ return null }; set{ /* do nothing */; }
}

Então você poderia ter um List<ICell<T>> que conteria itens e a próxima célula, e você poderia inserir EmptyCell no final (ou apenas tenha o Next referência explicitamente definida como nula).As vantagens seriam porque EmptyCell não contém variáveis ​​de membro, não exigiria nenhum espaço de armazenamento (como o empty em Haxe), enquanto um Cons célula faria.
O compilador também pode incorporar/otimizar os métodos em EmptyCell como eles não fazem nada, então pode haver um aumento de velocidade em relação a apenas ter um Cons com seus dados de membro definidos como nulos.

Eu realmente não sei.Acolheria com agrado quaisquer outras soluções possíveis, pois não estou particularmente orgulhoso da minha :-)

Outras dicas

Use um aula isso com propriedades estáticas para representar os valores de enumeração.Você pode, opcionalmente, usar um construtor privado para forçar todas as referências à classe a passarem por uma propriedade estática.

Dê uma olhada no System.Drawing.Color aula.Ele usa essa abordagem.

C# (o .NET framework em geral, até onde eu sei) não suporta enumerações parametrizadas como o Java.Dito isto, você pode querer dar uma olhada em Atributos.Alguns dos recursos que os enums Java são capazes podem ser realizados por meio de atributos.

O que há de errado em usar apenas uma classe para isso?É feio, mas foi assim que o pessoal de Java fez até ter suporte Enum integrado à linguagem!

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