Eu tenho um enum em um espaço para nome de baixo nível. Eu gostaria de fornecer uma classe ou enum em um espaço para nome de nível médio que "herda" a enum de baixo nível.
namespace low
{
public enum base
{
x, y, z
}
}
namespace mid
{
public enum consume : low.base
{
}
}
Espero que isso seja possível, ou talvez algum tipo de classe que substitua o consumo de enum, o que fornecerá uma camada de abstração para o enum, mas ainda permita que uma instância dessa classe acesse o enum.
Pensamentos?
EDIT: Uma das razões pelas quais eu não mudei isso para consts nas aulas é que o enum de baixo nível é necessário para um serviço que devo consumir. Recebi os WSDLs e os XSDs, que definem a estrutura como uma enumeração. O serviço não pode ser alterado.
Respostas:
Isso não é possível. Enums não podem herdar de outros enums. De fato, todas as enums devem realmente herdar
System.Enum
. O C # permite que a sintaxe altere a representação subjacente dos valores de enum que se parece com herança, mas na realidade eles ainda herdam do System.enum.Consulte a seção 8.5.2 da especificação da CLI para obter detalhes completos. Informações relevantes da especificação
System.Enum
fonte
switch
situações.Você pode conseguir o que deseja com as classes:
Agora você pode usar essas classes semelhantes como quando eram enumerações:
Atualização (após a atualização da pergunta):
Se você atribuir os mesmos valores int às constantes, conforme definido na enum existente, poderá converter entre a enum e as constantes, por exemplo:
fonte
Enum.GetValues(typeof(MyEnum)
void Test() { foreach (System.Reflection.PropertyInfo pi in typeof(Consume).GetProperties()) { Console.WriteLine(pi.Name); } }
A resposta curta é não. Você pode jogar um pouco, se quiser:
Você sempre pode fazer algo assim:
Mas, não funciona tão bem porque Base.A! = Consume.A
Você sempre pode fazer algo assim:
Para cruzar entre Base e Consumir ...
Você também pode converter os valores das enumerações em ints e compará-los como ints em vez de enum, mas esse tipo de coisa também é péssimo.
O método de extensão return deve digitar cast e digitar T.
fonte
Base.A == (Base)Consume.A
int
faria muito mais sentido. Quando um enum teria uma parte fracionária!?!?!As soluções acima, usando classes com constantes int, não possuem segurança de tipo. Ou seja, você pode inventar novos valores realmente não definidos na classe. Além disso, não é possível, por exemplo, escrever um método usando uma dessas classes como entrada.
Você precisaria escrever
No entanto, existe uma solução baseada em classe dos velhos tempos de Java, quando não havia enumerações disponíveis. Isso fornece um comportamento quase enum. A única ressalva é que essas constantes não podem ser usadas em uma instrução switch.
fonte
object
's faria os valores diferentes para cada instanciação da montagem, para que eles não possam ser serializados.Ignorando o fato de que base é uma palavra reservada, você não pode herdar enum.
A melhor coisa que você pode fazer é algo assim:
Como todos são do mesmo tipo base (ou seja: int), você pode atribuir o valor de uma instância de um tipo à outra que é convertida. Não é o ideal, mas funciona.
fonte
Eu sei que essa resposta está meio atrasada, mas foi o que acabei fazendo:
Então eu sou capaz de fazer coisas como:
fonte
Foi o que eu fiz. O que eu fiz de diferente é usar o mesmo nome e a
new
palavra-chave no "consumir"enum
. Como o nome doenum
é o mesmo, você pode usá-lo sem pensar e estará correto. Além disso, você obtém intellisense. Você só precisa tomar cuidado ao configurar que os valores são copiados da base e mantê-los sincronizados. Você pode ajudar isso junto com os comentários do código. Essa é outra razão pela qual, no banco de dados, ao armazenarenum
valores, eu sempre guardo a string, não o valor. Porque se você estiver usando valores inteiros crescentes atribuídos automaticamente, eles poderão mudar com o tempo.fonte
SmallMedium = 100,
), para manter a compatibilidade com versões mais antigas do seu software ao adicionar novos valores à classe base. Por exemplo, adicionar umHuge
tamanho à sua enum base seria atribuído4
ao seu valor, mas4
já é usadoSmallMedium
na classe derivada.Huge
na classe base seria necessário umHuge
na subclasse antesSmallMedium
BaseBall
pode não ser o nome mais inteligente aqui. Isto é confuso. Desde que uma bola de beisebol é realmente uma coisa. Se você sente falta de que essa é apenas uma classe básica para a bola, parece muito estranho que um voleibol herda de um beisebol fisicamente menor :). Minha sugestão é usar apenasBall
Solução alternativa
Na minha empresa, evitamos "pular projetos" para chegar a projetos de nível inferior não comuns. Por exemplo, nossa camada de apresentação / API só pode fazer referência a nossa camada de domínio e a camada de domínio pode fazer referência apenas à camada de dados.
No entanto, esse é um problema quando há enumerações que precisam ser referenciadas pelas camadas de apresentação e domínio.
Aqui está a solução que implementamos (até agora). É uma solução muito boa e funciona bem para nós. As outras respostas estavam acertando tudo isso.
A premissa básica é que enums não podem ser herdadas - mas classes podem. Assim...
Então, para "herdar" as enumerações em outro projeto de nível superior ...
Isso tem três vantagens reais ...
Para referenciar as enumerações no primeiro projeto , você pode usar o prefixo da classe: BaseEnums.StatusType.Pending ou adicionar um "using static BaseEnums;" declaração para seus usos.
No segundo projeto, ao lidar com a classe herdada, no entanto, não consegui trabalhar com a abordagem "using static ..." , portanto todas as referências às "enumerações herdadas" seriam prefixadas com a classe, por exemplo, SubEnums.StatusType.Pending . Se alguém tiver uma maneira de permitir que a abordagem "usando estática" seja usada no segundo projeto, informe-me.
Estou certo de que isso pode ser aprimorado para torná-lo ainda melhor - mas isso realmente funciona e eu usei essa abordagem em projetos de trabalho.
Faça um voto positivo se achar útil.
fonte
Eu também queria sobrecarregar a Enums e criei uma mistura da resposta de 'Seven' nesta página e da resposta de 'Merlyn Morgan-Graham' em um post duplicado , além de algumas melhorias.
Principais vantagens da minha solução sobre as demais:
Esta é uma solução pronta para uso e pode ser inserida diretamente no seu projeto. Ele foi projetado de acordo com minhas necessidades; portanto, se você não gostar de algumas partes, substitua-as por seu próprio código.
Primeiro, há a classe base da
CEnum
qual todas as enumerações personalizadas devem herdar. Possui a funcionalidade básica, semelhante aoEnum
tipo .net :Em segundo lugar, aqui estão duas classes Enum derivadas. Todas as classes derivadas precisam de alguns métodos básicos para funcionar como esperado. É sempre o mesmo código padrão; Ainda não encontrei uma maneira de terceirizá-lo para a classe base. O código do primeiro nível de herança difere um pouco de todos os níveis subsequentes.
As classes foram testadas com sucesso com o seguinte código:
fonte
Enums não são classes reais, mesmo que pareçam. Internamente, eles são tratados como seu tipo subjacente (por padrão, Int32). Portanto, você só pode fazer isso "copiando" valores únicos de uma enumeração para outra e convertendo-os em seu número inteiro para compará-los quanto à igualdade.
fonte
As enumerações não podem ser derivadas de outras enumerações, mas apenas de int, uint, short, ushort, long, ulong, byte e sbyte.
Como Pascal disse, você pode usar os valores ou constantes de outros enum para inicializar um valor de enum, mas é isso.
fonte
outra solução possível:
HTH
fonte
Isso não é possível (como @JaredPar já mencionado). Tentar colocar a lógica para solucionar isso é uma prática ruim. Caso você tenha um
base class
que tenha umenum
, deve listar tudo o que é possívelenum-values
lá e a implementação da classe deve funcionar com os valores que ele conhece.Por exemplo, suponha que você tenha uma classe base
BaseCatalog
e ela tenha umenum ProductFormats
(Digital
,Physical
). Então você pode ter umMusicCatalog
ouBookCatalog
que poderia conter ambosDigital
ePhysical
produtos, mas se a classe forClothingCatalog
, ela deverá conter apenasPhysical
produtos.fonte
Sei que estou um pouco atrasado para esta festa, mas aqui estão meus dois centavos.
Estamos todos claros de que a herança do Enum não é suportada pela estrutura. Algumas soluções muito interessantes foram sugeridas neste tópico, mas nenhuma delas parecia muito com o que eu estava procurando, então eu mesmo tentei.
Apresentando: ObjectEnum
Você pode verificar o código e a documentação aqui: https://github.com/dimi3tron/ObjectEnum .
E o pacote aqui: https://www.nuget.org/packages/ObjectEnum
Ou apenas instale:
Install-Package ObjectEnum
Em resumo,
ObjectEnum<TEnum>
atua como um invólucro para qualquer enumeração. Substituindo GetDefinedValues () nas subclasses, é possível especificar quais valores de enumeração são válidos para essa classe específica.Foram adicionadas várias sobrecargas de operador para fazer com que uma
ObjectEnum<TEnum>
instância se comporte como se fosse uma instância da enum subjacente, tendo em mente as restrições de valor definidas. Isso significa que você pode comparar facilmente a instância com um valor int ou enum e, portanto, usá-la em um caso de opção ou em qualquer outra condição.Gostaria de consultar a referência acima do repositório do github para exemplos e mais informações.
Espero que você ache isso útil. Sinta-se à vontade para comentar ou abrir um problema no github para mais pensamentos ou comentários.
Aqui estão alguns breves exemplos do que você pode fazer com
ObjectEnum<TEnum>
:fonte
Você pode executar herança em enum, no entanto, é limitado apenas aos seguintes tipos. int, uint, byte, sbyte, curto, ushort, longo, ulong
Por exemplo
fonte