2011-07-04 5 views
1

J'essaie de mettre en œuvre un tableau, divisé jusqu'à 3 niveaux. Maintenant, ma question n'est pas de la bonne façon de structurer cette implémentation, bien que tous les pointeurs seraient les bienvenus.Générique question en C#

iv'e a un problème avec la mise en œuvre d'un domaine générique classe

public class Field<T> 
{ 
    T value; 
    Type _type; 
    string _header; 
} 

je ne sais pas quel type T serait de si je dois définir la classe avec, maintenant le problème que je » m face est que la collection de Champ dans la classe enregistrement serait le plus probablement tenir différents types de Tet défaites un peu le tout usage

public class Record 
{ 
    List<Field<object>> fields ;   
} 

alors maintenant j'ai besoin de lancer le T à l'objet parce que T ne sera pas d'un type spécifique.

toute idée est le travail autour de cette acceptation tombant l'idée de tous les génériques et définissant la valeur comme objet, serait le plus apprécié.

plus tous les pointeurs sur mon idée de la mise en œuvre

ma table se compose de

class Table 
    { 
      KeyValuePair<string,Type>[] columns ; 
      KeyValuePair<string, Type> primary_key; 
      string entitie_name ; 
      List<Reocrd> records ; 
    } 
    // the Record class could be created only from a table template just like a datarow 
    public class Record 
    { 
      List<Field<object>> fields ; 
      string primary_key ;// the name of the field witch i use to extract a value    
    } 

10x à l'avance.

+3

vous semblez être de réinventer la roue? –

+0

Cela ne peut pas être fait avec des génériques seuls. Vous devrez: a) charger l'utilisateur de votre classe de demander un type spécifique de données, ou b) utiliser la génération de code pour créer des classes non génériques à partir de votre base de données, ou c) utiliser la réflexion. – Jon

+0

cela peut être une question naïve, mais pourquoi créez-vous des objets qui semblent imiter la datable ado.net, et datarow (et probablement datacolumn?)? – adrianos

Répondre

2

Un modèle que vous pouvez généralement trouver dans le .NET Framework est de définir une classe de base non-générique ou de l'interface:

public abstract class Field 
{ 
    protected Field() { } 

    public abstract BoxedValue { get; set; } 

    public abstract Type ValueType { get; } 
} 

public class Field<T> : Field 
{ 
    private T value; 

    public Field(T value) { this.value = value; } 

    public T Value 
    { 
     get { return this.value; } 
     set { this.value = value;; } 
    } 

    public override object BoxedValue 
    { 
     get { return this.value; } 
     set { this.value = (T)value; } 
    } 

    public override Type ValueType 
    { 
     get { return typeof(T); } 
    } 
} 

Le dossier classe expose une collection de champs non génériques:

public class Record 
{ 
    public IEnumerable<Field> Fields { get { ... } } 
} 

Si le code a besoin pour obtenir la valeur des champs sans la boxe, il a besoin de jeter l'instance de terrain pour la mise en correspondance Champ <T> premier.

Exemple:

foreach (Field<int> field in record.Fields.OfType<Field<int>>()) 
{ 
    int value = field.Value; 
    Console.WriteLine(value); 
} 
+0

10x qui m'a mis sur le bon chemin il y a juste 2 choses que je ne comprends pas, (1): vous ne pouvez pas avoir 2 classes nommées Champ (2): depuis quand une classe abstraite contient-elle un Constructeur –

+0

1. Vous pouvez avoir deux classes nommées Field si elles diffèrent par le nombre d'arguments génériques. 2. Les classes abstraites peuvent avoir des constructeurs, bien qu'elles ne puissent pas être instanciées. – dtb

0

je tendance à utiliser des interfaces ici

Ifield ... faire une classe générique qui utilise cette

hérite ensuite de cela avec un

Interface Ifield

maintenant, vous pouvez avoir un Liste qui contiendrait en fait une liste d'IField

interface IField 
{ 
object Data{get;set;} 
} 

interface IField<T> : IField 
{ 
T TypedObject{get;set;} 
} 

Vous pouvez maintenant ajouter une liste avec un objet IField.

EDIT: Je n'aime pas utiliser les classes de base, sauf si je dois vraiment parce que cela supprime alors la possibilité d'utiliser l'héritage plus tard. L'héritage est une solution simple, mais est livré avec toute une série de mises en garde imo