C# - 不知道变量类型如何初始化变量

8

我在数据库中有两个不同的表格,每个表格都基于它们的“SortOrder”向用户显示。我编写了两个函数,它们接受一行(或实体)并将其排序顺序与最近的一个交换(向上或向下,取决于执行哪个函数)。根据事件发生的位置(具有相同功能的多个网格视图),我需要使这些函数适用于两个不同的表格。以下是我目前的代码(再次说明,移动向下的几乎相同的函数,但我不会发布它,因为这将是冗余的):

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

明显的问题是,在if语句之前需要初始化"currentValue"变量,否则有可能永远不会被声明,因此使用当前值变量的函数的其余部分将无法工作。
我的问题是:如果我不确定它将是什么,应该如何在if语句之前初始化变量?我认为这可能会起作用,但它说我仍然需要初始化它("隐式类型本地变量必须初始化")。
    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);
    }

[编辑] 更改标题以更准确地反映我的问题

我并没有制作数据模型。我只是在一个已经基本构建完成的项目中添加功能。我对 .net 还非常陌生,所以我的知识有限。 - Jordan Foreman
你的问题在于 currentValue 的 _Type_,而不是它的值。只需要重新构建你的代码即可。 - H H
5个回答

9

在C#中,所有类型都需要一个类型。如果你的Table#类型继承自DataModel.DataAccess.Table,请使用以下代码:

DataModel.DataAccess.Table currentValue;

否则,您需要找到一个共同的基类(`object`是它们所有祖先中最老的)。
object currentValue;

由于您没有初始化currentValue,编译器无法知道您在var中指的是什么类型。这就是为什么会出现异常的原因。

补充说明:也许,您可以使用像这样的通用方法来代替传递表名:

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

或者你可以结合agent-j和我的方法,其中T是ISortableEntity,那么对实体的更改变得微不足道和抽象化,因此它们可以被添加或更改而不必更改这些函数。 - Jay

3

不要使用var,而是使用类型对象,尽管我可能会重写整个过程并使用一致(和标准)的命名约定。

因此:

object currentValue = null;

以这种方式,无论将变量转换为哪种类型,我都无法引用其SortOrder属性,因为object.SortOrder不存在。但这正是我希望能够做到的事情。 - Jordan Foreman

2
您可以尝试编写一个接口,每个实体都使用该接口,并编写一个接受该接口的函数。
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

你是否不知道变量的类型,因此隐式(使用“var”,而不是例如“int”)声明它?

对于显式类型,您无需初始化 - 隐式类型需要初始化,因为它们通过给定的值确定其类型。


0
解决方案是接口。您的Table 1 和 Table 2 类应该实现一个接口(例如 ISortableTable 或者您想要的任何名称),并带有一个 CurrentValue 属性。Table1 的 CurrentValue 属性实现将返回 Table1 的正确结果,而 Table2 的 CurrentValue 属性将返回 Table2 的正确结果。然后,您的排序函数就可以与实现 ISortableInterface 接口的任何类一起工作,并使用相应对象的 CurrentValue 属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接