C# - Initialize a variable without knowing what its going to be
Asked Answered
S

5

8

I have two different tables in my database, and each are displayed to the user based on their "SortOrder". I have written two functions that take a row (or entity) and swaps its sort order with the one nearest it (up or down, depending on which function is being executed). I need to make these functions work for two different tables, depending on where the event is occurring (multiple gridviews with identical functionality). Here is what I have so far (again, there is an almost identical function for moving down, but I won't post that because it would be redundant):

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)
        {
        }
    }

The obvious problem is that I need to initiate the currentValue variable before the if statements, otherwise there is the "possibility" of it never being declared, and therefore the rest of the function (that utilizes the currentValue variable), won't work.

My question is this: How should I initialize the variable before the if statements, if I'm not sure what its going to be yet? I thought that this might work, but it says I still need to initialize it ("implicitly-typed local variables must be initialized"):

    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] Changed the title to make it more accurately reflect my question

Surpass answered 28/6, 2011 at 18:6 Comment(2)
I didn't make the datamodel. I'm just adding functionality to a project that is already mostly built. I'm still very new to .net, so I'm working with limited knowledgeSurpass
You have a problem with the Type of currentValue, not with the value. Just restructure your code.Separable
A
9

In C#, all types need a type. If your Table# types extend DataModel.DataAccess.Table, use this:

DataModel.DataAccess.Table currentValue;

Otherwise, you'll need to find a common base class (object being the great-granddaddy of them all).

object currentValue;

Since you didn't initialize currentValue, the compiler can't know what type you mean by var. That's why you are getting the exception.

Addendum: Perhaps, instead of passing in the name of the table, you can use a generic method, like this:

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)
    {
    }
}
Aurignacian answered 28/6, 2011 at 18:10 Comment(1)
Or you can do a combination of agent-j's and mine, where T is ISortableEntity, then your changes to the entity become trivial and abstracted so they can be added to or changed without changing these functions.Jephthah
H
3

Instead of var, use type object although I would probably rewrite this whole proc and use consistent (and standard) naming conventions.

so:

object currentValue = null;
Hypotenuse answered 28/6, 2011 at 18:9 Comment(1)
in this way, I can't reference the SortOrder property of the variable, regardless of which type it ends up being cast as, since object.SortOrder doesn't exist. But this is the kind of thing I was hoping to be able to do.Surpass
J
2

You can try writing an interface which each entity uses and a function that accepts that 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();
    }
}
Jephthah answered 28/6, 2011 at 18:12 Comment(0)
G
0

Do you not know the type of the variable, which is why you're declaring it implicitly ('var', as opposed to, say, 'int')?

You don't have to initialize explicit types - implicit types require it because they figure out their type by the value given.

Glyceric answered 28/6, 2011 at 18:11 Comment(0)
L
0

The solution is interfaces. Your Table 1 and Table 2 classes should implement an interface (such as ISortableTable or whatever you want to call it) with a property for CurrentValue. Table1's CurrentValue property implementation would return the correct result for Table1 and Table2's CurrentValue property would return the correct result for Table2. Then your sorting function can work with any class that implements the ISortableInterface and work with the respective object's CurrentValue property.

Lathan answered 28/6, 2011 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.