11
votes

Quel est l'équivalent C # de la classe de Java type?

en Java, il est pratique pour la classe d'avoir le paramètre générique, X. Mais la classe de type C # 'S # n'a pas cela.

Ainsi, dans C #, comment est-ce que l'équivalent du code Java suivant?: P>

public <X> X methodThatReturns(Class<X> clazz) { ... }


4 commentaires

msdn.microsoft.com/en-us/Library /ms379564(V=VS.80).aspx


Je ne suis pas une grande partie d'un programmeur C #, mais je pense que cet idiome est beaucoup moins courant dans C # car c # n'a pas d'effacement de type. Les informations de type générique sont conservées, non perdues, au moment de l'exécution.


Ne pense pas qu'il y en a un.


Note à @slattery: Les génériques ont été ajoutés à partir de .NET 2.0 / C # 2 / Visual Studio 2005. Si vous utilisez .NET 1.1 / C # 1.2 / Visual Studio 2002/2003, vous n'avez pas de chance.


4 Réponses :


9
votes
public X methodThatReturns<X>()
{
    Type xType = typeof(X); // Type is to C#/.Net what Class<X> is to Java.
}

3 commentaires

Merci Ivan, mais je cherche votre méthode pour prendre un "type" de x comme paramètre, plutôt qu'une instance de x ... quelque chose comme le type .


Aucun moyen de le prendre en tant que paramètre, mais en C #, vous n'avez pas besoin de le faire comme vous pouvez le faire dans la méthode même s'il n'a pas de paramètre: type x = typeof (x) . Le type est l'équivalent de la classe en C #.


C'est très malheureux. Pour ne pas avoir un moyen d'exprimer un type de retour dynamique via le type transmis et obtenir la vérification du type de compilateur est très limitée pour certains cas.



3
votes

en C #, il serait xxx

et vous pouvez obtenir le type de x à l'aide de typeof (x) au lieu d'utiliser le paramètre Clazz


0 commentaires

1
votes

Je ne suis pas à 100% sur les génériques Java ... essayez-vous de déclarer une méthode qui renvoie le même type qu'il a été transmis?

public T MethodThatReturns<T>()
{
    Type clazz = typeof(T);
    ....
}


0 commentaires

0
votes

Je connais avec Java et .NET Generics et j'utilise la classe code> Construisez beaucoup dans mes projets Java. L'une de mes utilisations préférées est de gérer des collections non génériques de Java qui sont renvoyées du code extérieur comme Hibernate (je pense que la dernière version de Hibernate pourrait soutenir des génériques, bien que je ne suis pas certain. Nous utilisons plutôt une Vieille version de celui-ci puisqu'il s'agit d'un projet de longue date qui a trop de code qui devrait être mis à jour si nous l'avons jamais changé.) La fonction fonctionne comme ceci: xxx pré>

C'est tout très simple et la chose importante est que je n'ai pas à créer un objet factice à passer à la fonction, je viens de l'appeler comme suit: p> xxx pré>

une autre chose importante à noter est que le Le paramètre CLS n'est pas utilisé du tout. C'est seulement un moyen de donner un type de béton pour x. P>

la façon dont vous faites la même chose est un peu différent dans C #. Vous pensez peut-être que la même fonction ressemblerait à ceci comme ceci: p> xxx pré>

mais vous seriez mauvais. EM> P> P>

Le Le problème est que Java utilise une astuce appelée Erasure EM>, qui signifie essentiellement que lorsque le code est en réalité compilé, tous les paramètres génériques sont supprimés du code. Donc, dans le monde de la machine virtuelle Java, il n'y a pas une telle chose qu'une liste code> ou tout autre générique, elles sont toutes simples Liste code> et autres non génériques les types. Cela signifie que les génériques ne sont là que là pour vous aider à coder et ne sont pas appliqués au moment de l'exécution. P>

en C #, il n'y a pas d'effacement de type et de génériques sont forts> appliqués au moment de l'exécution. Cela signifie que les éléments suivants généreraient une exception d'exécution lorsqu'il serait utilisé avec la fonction ci-dessus: p> xxx pré>

la raison est que list code> et Liste code> sont considérées comme deux classes complètement différentes. Vous ne pouvez même pas faire list lstobj = (liste ) nouvelle liste (); code> sans obtenir une erreur de compilateur. cela signifie que la fonction ne peut pas renvoyer le même objet qui lui a été transmis. em> nous doit strong> créer un nouvel objet du type correct et renvoyer celui-ci. La forme la plus élémentaire de cela ressemblerait aux éléments suivants: p>

List<long> lstLng = new List<long>();
lstLng.Add(1);
List<int> lstInt = lstLng.Cast<int>().ToList();
List<string> lstStr = lstLng.Select(lng => lng.ToString()).ToList();


3 commentaires

Lire intéressante. Je suis content que vous ayez trouvé ces méthodes LINQ utiles dans votre situation actuelle. Je ne pense pas qu'il y ait quelque chose de spécial caché derrière eux, cependant. J'ai créé ma propre méthode d'extension detype avant de réaliser qu'il y avait déjà une intégrée. Les limitations d'aller de la liste à une liste ont probablement plus à voir avec la variance de type. J'utilise toujours C # 3.5, mais je pense que 4.0 a introduit plus de soutien pour cela (comme les mots-clés "dans" et "Out" pour la covariance et la contravérie).


@slattery en fait, la variance ne s'applique pas aux classes, uniquement des interfaces et des délégués. La liste est implémente iEnumérable, qui est covariante cependant, vous pouvez donc faire quelque chose comme ienumerable énumobj = nouvelle liste (); mais vous ne pouviez toujours pas suivre la liste Objet> lstobj = (liste ) Enumobj; sans exception de distribution car le type de béton va toujours être la liste . Ainsi, lorsque vous faites quelque chose comme list lstobj = lstr.oftype (). Tolist (); Un tout nouvel objet de liste est créé et attribué.


@slattery Consultez cet article pour plus d'informations sur la variance: MSDN.MicRosoft.com/ EN-US / Bibliothèque / DD799517.aspx . Il est intéressant de noter que ienumbertables est une variante et une icollection n'est pas. Je pense que c'est parce que certaines des méthodes définies dans l'ICollection prennent T comme paramètre. (Contravariance décède toujours avec mon esprit ... lol) merci pour vos commentaires cependant. ;-)