Existe um equivalente typedef em C # ou alguma forma de obter algum tipo de comportamento semelhante? Eu pesquisei no Google, mas em todos os lugares que olho parece ser negativo. Atualmente, tenho uma situação semelhante à seguinte:
class GenericClass<T>
{
public event EventHandler<EventData> MyEvent;
public class EventData : EventArgs { /* snip */ }
// ... snip
}
Agora, não é preciso um cientista de foguetes para descobrir que isso pode rapidamente levar a muitas digitações (desculpas pelo trocadilho horrível) ao tentar implementar um manipulador para esse evento. Acabaria sendo algo assim:
GenericClass<int> gcInt = new GenericClass<int>;
gcInt.MyEvent += new EventHandler<GenericClass<int>.EventData>(gcInt_MyEvent);
// ...
private void gcInt_MyEvent(object sender, GenericClass<int>.EventData e)
{
throw new NotImplementedException();
}
Exceto, no meu caso, eu já estava usando um tipo complexo, não apenas um int. Seria bom se fosse possível simplificar um pouco ...
Editar: ie. talvez digitando o EventHandler em vez de precisar redefini-lo para obter um comportamento semelhante.
using MyClassDictionary = System.Collections.Generic.Dictionary<System.String, MyNamespace.MyClass>;
Está correto? Caso contrário, não parece considerar asusing
definições acima.typedef uint8 myuuid[16];
através da diretiva "using".using myuuid = Byte[16];
não compila.using
pode ser usado apenas para criar aliases de tipo .typedef
parece ser muito mais flexível, pois pode criar um alias para uma declaração inteira (incluindo tamanhos de matriz). Existe alguma alternativa neste caso?Jon realmente deu uma boa solução, eu não sabia que você poderia fazer isso!
Às vezes, recorri a herdar da classe e criar seus construtores. Por exemplo
Não é a melhor solução (a menos que sua montagem seja usada por outras pessoas), mas funciona.
fonte
public class FooList : LikeType<IReadOnlyList<Foo>> { ... }
e depois usá-lo em qualquer lugar que você esperariaIReadOnlyList<Foo>
. Minha resposta abaixo mostra mais detalhes.Foo
se passado para, por exemplo, o método de modelo que aceitaList<T>
. Com o typedef adequado, seria possível.Se você souber o que está fazendo, poderá definir uma classe com operadores implícitos para converter entre a classe de alias e a classe real.
Na verdade, eu não aprovo isso e nunca usei algo assim, mas isso provavelmente poderia funcionar em algumas circunstâncias específicas.
fonte
O C # suporta alguma covariância herdada para delegados de eventos, portanto, um método como este:
Pode ser usado para se inscrever no seu evento, sem necessidade de transmissão explícita
Você pode até usar a sintaxe lambda e o intellisense será feito para você:
fonte
Eu acho que não há typedef. Você só pode definir um tipo de delegado específico em vez do genérico na GenericClass, ou seja,
Isso tornaria mais curto. Mas e a seguinte sugestão:
Use o Visual Studio. Dessa forma, quando você digitou
ele já fornece a assinatura completa do manipulador de eventos do Intellisense. Pressione TAB e está lá. Aceite o nome do manipulador gerado ou altere-o e pressione TAB novamente para gerar automaticamente o stub do manipulador.
fonte
C ++ e C # estão faltando maneiras fáceis de criar um novo tipo que é semanticamente idêntico a um tipo existente. Acho esses 'typedefs' totalmente essenciais para a programação com segurança de tipos e é uma pena que o c # não os tenha embutidos. A diferença entre
void f(string connectionID, string username)
tovoid f(ConID connectionID, UserName username)
é óbvia ...(Você pode obter algo semelhante em C ++ com aumento em BOOST_STRONG_TYPEDEF)
Pode ser tentador usar herança, mas isso tem algumas limitações principais:
A única maneira de conseguir algo semelhante em C # é compondo nosso tipo em uma nova classe:
Embora isso funcione, é muito detalhado apenas para um typedef. Além disso, temos um problema de serialização (isto é, para Json), pois queremos serializar a classe através de sua propriedade Composed.
Abaixo está uma classe auxiliar que usa o "Padrão de Modelo Curiosamente Recorrente" para tornar isso muito mais simples:
Com o Composer, a classe acima se torna simplesmente:
E além disso, o
SomeTypeTypeDef
serializará para o Json da mesma maneira queSomeType
faz.Espero que isto ajude !
fonte
Você pode usar uma biblioteca de código aberto e um pacote NuGet chamado LikeType que eu criei que fornecerão o
GenericClass<int>
comportamento que você está procurando.O código ficaria assim:
fonte
LikeType
biblioteca.LikeType
Seu principal objetivo é ajudar com a Obsessão primitiva e, como tal, não deseja que você possa passar pelo tipo de quebra automática como se fosse o tipo de quebra automática. Por exemplo, se eu fizerAge : LikeType<int>
isso, se minha função precisar de umAge
, quero garantir que meus chamadores estejam passando umAge
, não umint
.Aqui está o código, aproveite !, peguei no dotNetReference o tipo "using" na linha de namespace 106 http://referencesource.microsoft.com/#mscorlib/microsoft/win32/win32native.cs
fonte
Para classes não seladas, simplesmente herde delas:
Mas para classes seladas é possível simular o comportamento de typedef com essa classe base:
fonte
A melhor alternativa para a
typedef
que encontrei em C # éusing
. Por exemplo, eu posso controlar a precisão de flutuação por meio de sinalizadores de compilador com este código:Infelizmente, é necessário que você coloque isso no topo de todos os arquivos em que você usa
real_t
. No momento, não há como declarar um tipo de espaço para nome global em C #.fonte