C# résumé struct
Comment puis-je obtenir de l'héritage (ou similaire) avec les structures en C#?
Je sais qu'un résumé, la structure n'est pas possible, mais j'ai besoin de réaliser quelque chose de similaire.
J'ai besoin d'elle comme d'une struct, car il doit être d'un type valeur. Et j'ai besoin d'héritage, car j'ai besoin d'un générique de tableau et les méthodes que je vous garantissons sont là.
Je pense qu'un exemple ira un long chemin, si heres un code qui ne compile pas, mais montre ce que je veux atteindre;
abstract struct Vertex
{
abstract int SizeInBytes;
abstract void SetPointers();
}
struct ColorVertex : Vertex
{
Vector3 Position;
Vector4 Color;
override int SizeInBytes //static
{
get { return (3 + 4) * 4; }
}
override void SetVertexPointers() //static
{
...
}
}
class main
{
static void main()
{
Vertex[] verts = new Vertex[3];
for(int i = 0; i < 3; i++)
verts[i] = new ColorVertex();
verts[0].SetVertexPointers(); //should call ColorVertex.SetVertexPointers
externalAPIcall(verts);
}
}
EDIT:
La raison que j'ai besoin de types de valeur est ainsi que je peux faire un tableau d'entre eux, et de passer à OpenGL comme un vertex buffer. Pour cela, les données doivent être directement contenus dans ce tableau.
Je serais surpris si ce n'étaient tout simplement pas possible de réaliser.
OriginalL'auteur Hannesh | 2011-02-15
Vous devez vous connecter pour publier un commentaire.
À la lumière de vos récents edit:
Il semble que la réel solution pour vous est d'encapsulation. Si la mise en page de votre
struct
est dicté par une API tierce (de sorte que vous pouvez interagir avec du code non managé), alors vous devriez vraiment envisager d'emballage l'API types dans les classes appropriées plutôt que d'essayer d'interagir avec eux directement dans le code.Pour l'un, vous dites ceci:
Ce n'est pas la façon dont vous vous attendez. Comme d'autres l'ont souligné, la seule manière de définir un ensemble commun d'une fonctionnalité qui peut s'appliquer à des structures est par l'intermédiaire d'interfaces (par exemple, les types primitifs .NET mettre en œuvre
IComparable
). Malheureusement, si vous déclarez un tableau de typeIYourInterface
, toutes les valeurs obtiendrez en boîte (interface références sont des types référence, même si la valeur sous-jacente elles sont pointant vers sont des types de valeur).Par exemple, disons que vous déclarez un
IVertex
interface:Et vous avez un ou plusieurs types de valeur que sa mise en oeuvre:
Chaque fois que vous faites cela:
La deuxième ligne de la valeur de
myVertex
et de stocker une référence à cette boîte de valeur dansfoo
. Comme les tableaux sont juste une série de variables, les mêmes règles s'appliquent:Toutes les valeurs de
foos
sera en boîte, et de leurs références stockées. C'est différent que si vous avez fait:Où aucun de boxe est nécessaire.
Cela a des conséquences directement liées à ce que vous recherchez, comme la boxe, les valeurs maintenant signifie que vous n'avez plus d'un bloc contigu de valeurs (le bien, vous le faites, mais le contiguë bloc de références; les valeurs elles-mêmes sont ailleurs).
Encapsulation
Compte tenu du fait que vous
Vous devriez vraiment envisager d'enveloppement de l'API OpenGL. Par exemple, disons que vous disposez des éléments suivants:
Ce qui est probablement une meilleure option serait de définir votre propre interface, puis se cacher OpenGL API:
(C'est évidemment un exemple artificiel, mais il doit démontrer ce que je suis en train de faire en termes d'introduction d'une couche d'abstraction entre votre code et les autres API)
T returnSmaller<T>(ref T p1, ref T p2) where T:IComparable<T> {return p1.CompareTo(p2) < 0 ? p1 : p2;}
(j'ai utiliséref
paramètres pour éliminer un couple d'extra struct des opérations de copie, même si certains continuent à être nécessaires; il n'y a pas de boxe en tout cas).OriginalL'auteur Adam Robinson
En C#, vous pouvez utiliser les interfaces pour obtenir quelque chose qui ressemble à du polymorphisme avec des types de valeur (struct) que vous ne pouvez pas tirer directement à partir d'un
struct
mais vous pouvez avoir plusieursstruct
types de mettre en œuvre des interfaces spécifiques.Par conséquent, au lieu de votre résumé
struct
,Vertex
, vous pouvez avoir une interface,IVertex
.Cependant, il est extrêmement rare que vous avez besoin pour mettre en œuvre vos propres types de valeur, donc assurez-vous que vous avez vraiment besoin de type de la valeur sémantique avant de continuer. Si vous ne mettre en œuvre vos propres types de valeur, assurez-vous qu'ils sont immuables que mutable types de valeur sont une porte d'entrée pour toutes sortes d'horribles problèmes.
Vous devez être conscient que la boxe va se produire lors de la conversion d'un type de valeur à une interface. Ceci n'a pas seulement avoir des conséquences si vos types de valeur sont mutables (ne pas le faire mutable types de valeur), mais cela va diminuer, ou, plus probablement annuler toute mémoire avantage vous pouvez gagner de l'utilisation d'un type de valeur, selon le moment ou la façon de le faire et si vous le faites pour chaque valeur - utiliser un profiler si vous n'êtes pas sûr.
J'ai déjà mis à jour pour couvrir cela. Merci!
Bwahahahah la même page, j'avais regardé pour vérifier si il est vrai que je me suis souvenu sur les structures et les interfaces 🙂 🙂
Il est également intéressant de noter que la boxe va supprimer toute la mémoire de l'avantage que l'utilisation d'un type de valeur.
Si vous downvoted, s'il vous plaît dites-moi pourquoi. J'aimerais assurez-vous que cette réponse est correcte, car il peut être. Merci.
OriginalL'auteur Jeff Yates
Vous ne pouvez pas, dans le fond. Vous ne pouvez pas tirer à partir d'une struct. Pourquoi pensez-vous que vous voulez une structure plutôt qu'une classe? Vous dites "il a à un type de valeur" - pourquoi? De même pensez-vous de l'héritage est la seule option à la place de (disons) de la composition? Par exemple, vous pourriez utiliser:
Vous êtes tout simplement pas va être en mesure d'obtenir un "abstract struct" ou quelque chose de semblable à travailler, alors je vous suggère de vous expliquer le raisons derrière votre unsatisfiable exigences, au lieu de juste dire comme des exigences qui ne peuvent pas être évités.
C'est exactement le genre de chose que les OP doit pour dire alors, au lieu de "il a à un type de valeur".
Vous pouvez le faire, si vous tournez Vertex dans une interface au lieu d'une classe.
a) qui est alors pas un type de valeur, comme un soi-disant nécessaire; b) lorsqu'il crée un tableau de type
Vertex[]
ce sera la fin de la boxe tout à valeur ajoutée, qui sera probablement retirer la moitié de la point de l'utilisation de structures tout.Eh bien, si vous avez ColorVertex vous pouvez faire quelque chose comme si(cv est IVertex), cv restera un type de valeur. Mais vous avez raison, toute opération qui aurait pour résultat de boxe serait probablement à l'encontre du but.
OriginalL'auteur Jon Skeet
Une sous-estimée en fonction des types de valeur .net, c'est qu'ils peuvent être passés comme interface limitées types génériques sans la boxe. Par exemple:
Notez que j'ai utilisé
ref
paramètres pour éliminer supplémentaires copies temporaires des deux paramètres; une copie supplémentaire dup2
sera faite quand ils sont passés à laCompareTo
méthode, et au moins une copie supplémentaire sera probablement rendu lorsque le résultat est renvoyé, mais faire deux copies redondantes serait mieux que de faire quatre. Dans tous les cas, la méthode ci-dessus ne peut être invoquée sans la boxe sur n'importe quel typeT
qui implémenteIComparable<T>
.Malheureusement, il n'y a pas terriblement belle façon de dire "si
T
est un type de structure, le passer à une méthode qui prend ce type; sinon si c'est un autre type, passer à une méthode et à prendre celui-là". Ainsi, le code, qui exigent une exacte classe (comme le code à l'aide de l'API) devra probablement être non-générique. Néanmoins, si il y a quelques méthodes qui devraient être utilisable sur une variété de structures, ceux-ci ayant des structures d'implémenter des interfaces puis de les transmettre en tant que contrainte types génériques peut offrir des avantages considérables.OriginalL'auteur supercat
Vous pouvez utiliser les interfaces
OriginalL'auteur ja72
Il ressemble à ce que vous voulez est une interface.
Une interface de sens puisque l'ensemble de vos méthodes sont déclarées abstrait (ce qui signifie qu'il s'appuie sur dérivant des classes pour mettre en œuvre la méthode qui consiste essentiellement en ce que l'interface est)
OriginalL'auteur Marlon
Vous pouvez créer une interface IVertex et puis l'ajouter à Vos structures.
OriginalL'auteur Damian Leszczyński - Vash
Peut-être vous pouvez utiliser un "l'union" type:
N'oubliez pas de rendre immuable et d'accéder uniquement les champs qui ont du sens pour chaque type.
OriginalL'auteur Jordão
Classes peuvent être "types de valeur" (dans le sens utilisé dans le Domain Driven Design). Tout ce que vous avez à faire c'est immuable, faire les constructeurs inaccessibles au grand public (Protégés ou à l'interne), et de créer statique usine méthodes pour créer des instances de leur contrôle et de leur instanciation, et n'ont aucun setters sur vos biens...
REMARQUE: L'expression Type de Valeur dans ce contect n'a rien à voir avec le type de Valeur vs Type de Référence. Il a à voir avec Type de Valeur vs Type d'Entité employé dans le Domaine Drtiven Design ou un Domaine de Modélisation...
Le type de valeur que distinquished de Types d'Entité, et non pas comme distinquished de types de référence ...
Malheureusement, les classes ne peuvent pas être d'un type valeur. Il y a quelques faibles différences de niveau entre la valeur et les types référence, en particulier si elles sont allouées sur le tas ou de la pile. Voir: albahari.com/valuevsreftypes.aspx
J'ai peut-être tort, mais la lecture de la question, qu'est ce que je pense qu'il parle... Sinon, pourquoi aurait-il dit "ça doit être une struct parce qu'il a une "Valeur Type" S'il voulait dire la même chose des deux phrases????
Je ne veux pas argumenter (et je ne vais pas plus loin; je vais laisser les downvotes parlent d'eux-mêmes), mais cette interprétation est qu'un seul qui fait croire que si l'OP ne sais pas ce que
struct
moyens (il n'y a aucune raison qu'il doit être unstruct
si c'est une question de simplement exiger l'immuabilité), plutôt qu'une simple étrangère déclaration. Vous parlez d'une seule phrase, c'est tangentielle à la véritable nœud de la question, qui est de savoir si ou non il est possible d'utiliser l'héritage avec les types de valeur.OriginalL'auteur Charles Bretana