2011-06-28 1 views
4

J'ai deux tables différentes dans ma base de données, et chacune est affichée à l'utilisateur en fonction de leur "SortOrder". J'ai écrit deux fonctions qui prennent une ligne (ou une entité) et inversent son ordre de tri avec celui qui est le plus proche (haut ou bas, selon la fonction en cours d'exécution). J'ai besoin de faire fonctionner ces fonctions pour deux tables différentes, en fonction de l'endroit où l'événement se produit (gridviews multiples avec des fonctionnalités identiques). Voici ce que j'ai jusqu'à présent (encore une fois, il y a une fonction presque identique pour le déplacement vers le bas , mais je ne publierez pas parce que ce serait redondant):C# - Initialise une variable sans savoir ce que cela va être

protected void moveUp(String ValId, String dbName) 
    { 
     int ValueId = Convert.ToInt32(ValId); 
     DataModel.DataAccess.Entities dc = new DataModel.DataAccess.Entities(); 
     if (dbName.ToLower() == "table1") 
     { 
      DataModel.DataAccess.Table1 currentValue = dc.Table1.Single(table1item => table1item.Table1ItemId == ValueId); 
     } 
     else if (dbName.ToLower() == "table2") 
     { 
      DataModel.DataAccess.Table2 currentValue = dc.Table2.Single(table2item => table2item.Table2ItemId == ValueId); 
     } 
     try 
     { 
      //make the change and update the database and gridview 
     } 
     catch (InvalidOperationException) 
     { 
     } 
    } 

Le problème évident est que j'ai besoin pour initier le currentValue variable avant les instructions if, sinon il y a la "possibilité" de ne jamais être déclaré, et donc le reste de la fonction (qui utilise la variable currentValue), ne fonctionnera pas.

Ma question est la suivante: comment dois-je initialiser la variable avant les instructions si, si je ne suis pas sûr de ce que ça va être encore? Je pensais que cela pourrait fonctionner, mais il me dit que je dois encore l'initialiser (« variables locales implicitement typées doivent être initialisées »):

var currentValue; //this is the line where I get the error message above 
    if (dbName.ToLower() == "table1") 
    { 
     currentValue = (DataModel.DataAccess.Table1)dc.Table1.Single(table1item => table1item.Table1ItemId == ValueId); 
    } 
    else if (dbName.ToLower() == "table2") 
    { 
     currentValue = (DataModel.DataAccess.Table2)dc.Table2.Single(table2item => table2item.Table2ItemId == ValueId); 
    } 

[EDIT] a changé le titre pour qu'il reflète plus précisément ma question

+0

Je n'ai pas créé le modèle de données. J'ajoute simplement des fonctionnalités à un projet qui est déjà principalement construit. Je suis encore très nouveau pour .net, donc je travaille avec des connaissances limitées –

+0

Vous avez un problème avec le _Type_ de currentValue, pas avec la valeur. Juste restructurer votre code. –

Répondre

7

En C#, tous les types ont besoin d'un type. Si vos Table# types étendent DataModel.DataAccess.Table, utilisez ceci:

DataModel.DataAccess.Table currentValue; 

Sinon, vous aurez besoin de trouver une classe de base commune (objet étant le grand-grand-papa de tous).

object currentValue; 

Puisque vous ne l'avez pas initialisez currentValue, le compilateur ne peut pas savoir quel type vous entendez par var. C'est pourquoi vous obtenez l'exception.

Addendum: Peut-être, au lieu de passer au nom de la table, vous pouvez utiliser une méthode générique, comme ceci:

moveUp(dc.Table1, item => item.Table1Key, "george"); 

void moveUp<T> (IEnumerable<T> table, Func<T,string> keySelector, string ValId) 
{ 
    T currentValue = table.Single(item => keySelector(item) == ValueId); 

    try 
    { 
     //make the change and update the database and gridview 
    } 
    catch (InvalidOperationException) 
    { 
    } 
} 
+0

Ou vous pouvez faire une combinaison de l'agent-j et le mien, où T est ISortableEntity, alors vos changements à l'entité deviennent triviaux et abstraits afin qu'ils puissent être ajoutés ou modifiés sans changer ces fonctions. – Jay

2

Au lieu de var, utilisez l'objet type bien que je réécrive probablement tout ce proc et j'utilise des conventions de nommage cohérentes (et standard).

donc:

object currentValue = null; 
+0

de cette manière, je ne peux pas référencer la propriété SortOrder de la variable, quel que soit le type dont elle est convertie, car object.SortOrder n'existe pas. Mais c'est le genre de chose que j'espérais pouvoir faire. –

0

Connaissez-vous pas le type de la variable, ce qui est pourquoi vous re le déclarer implicitement ('var', par opposition, disons, 'int')?

Vous n'avez pas besoin d'initialiser les types explicites - les types implicites l'exigent car ils déterminent leur type par la valeur donnée.

2

Vous pouvez essayer d'écrire une interface utilisée par chaque entité et une fonction qui accepte cette interface.

public interface ISortableEntity 
{ 
    int ID { get; set; } 
    int SortOrder { get; set; } 
} 


public class DataFunctions 
{ 
    public static void MoveUp(string dbName, int valID) 
    { 
     var db = //Get your context here; 
     List<KeyValuePair<string, object>> keys = new List<KeyValuePair<string, object>>(); 
     keys.Add(new KeyValuePair<string, object>("ID", valID)); 

     ISortableEntity entity = db.GetObjectByKey(new System.Data.EntityKey(dbName, keys)) as ISortableEntity; 

     if (entity != null) 
     { 
      entity.SortOrder += 1; 
     } 

     db.SaveChanges(); 
    } 
} 
0

La solution est des interfaces. Vos classes Table 1 et Table 2 doivent implémenter une interface (telle que ISortableTable ou tout ce que vous voulez appeler) avec une propriété pour CurrentValue.L'implémentation de la propriété CurrentValue de Table1 retournera le résultat correct pour Table1 et la propriété CurrentValue de Table2 retournera le résultat correct pour Table2. Ensuite, votre fonction de tri peut fonctionner avec n'importe quelle classe qui implémente l'ISortableInterface et travaille avec la propriété CurrentValue de l'objet respectif.

Questions connexes