【问题标题】:Define anonymous variable without initialization and use it in switch statement定义不初始化的匿名变量并在switch语句中使用
【发布时间】:2014-01-13 09:36:25
【问题描述】:

是否可以定义一个匿名变量并在switch 语句中使用它?

类似这样的:

我需要定义一个IEnumerable 类型来实际循环遍历DbContext 中的实体类型。

DAL.DataClasses1DataContext _db = new DAL.DataClasses1DataContext();
var dbItems;

switch (tableName)
{
     case "QuarryCats" : 
         dbItems = _db.QuarryCats.ToList();
         break;
}

foreach (var item in dbItems)
{
    var orderitem = orderItems.Single(rs => rs.itemId == item.Id);
    item.OrderId = orderitem.orderId;
}

_db.SubmitChanges();

目前我得到一个编译时错误:

隐式类型局部变量必须初始化

更新: 我所有来自 swich 的返回类型都有 Id 和 OrderId 字段。需要我投吗?

【问题讨论】:

  • 错误状态本身,这是不可能的,因为 var 在初始化期间暗示了类型。您必须在使用前对其进行初始化。
  • var 不代表匿名类型。它只是一个隐式类型的变量。那是同一件事。
  • 谢谢,但是如何在 swich statment 中定义隐式类型和初始化
  • _db.QuarryCats.ToList() 返回什么?
  • _db 是 DataClasses1DataContext 类型

标签: c# .net types


【解决方案1】:

嗯,“var”要求变量类型应该在编译时定义,例如

  var myVar = 1 + 5 / 7.8; // <- Compiler can elaborate that myVar is double

在您的情况下,myAnonymous 的类型 取决于 tableName 值 - 哪种情况将是 已执行,-所以myAnonymous 的类型是运行时间定义的,这是被禁止的。

  var myAnonymous; // <- Unknown type, can't be elaborated!

  switch (tableName) {
    case "QuarryCats" : 
      myAnonymous = 123; // <- Here it's int

      break;
    case "SomeOther":
      myAnonymous = "ABC"; // <- Here it's String 

但是,您可以使用 run time 类型定义:

  dynamic myAnonymous;

  switch (tableName) {
    case "QuarryCats" : 
      myAnonymous = ...

【讨论】:

    【解决方案2】:

    试试这个:

    IEnumerable<object> myAnonymous = new List<object>();
    
    switch (tableName)
    {
       case   "QuarryCats" : myAnonymous= _db.QuarryCats.ToList();
       break;
    }
    
    foreach (var item in myAnonymous)
    {
    }
    

    如果您知道 _db.QuarryCats.ToList() 返回的类型,请使用 IEnumerable&lt;object&gt; 而不是 IEnumerable&lt;object&gt;。因此,如果_db.QuarryCats.ToList() 返回QuarryCats,请使用IEnumerable&lt;QuarryCats&gt;

    【讨论】:

      【解决方案3】:

      尽管如前所述,使用dynamic 可以解决此问题,但我宁愿考虑更多强类型的解决方案。这里重要的是您的开关分配了一个集合以供以后枚举。因为这很常见,所以我会将它用作一种类型:

      IList myAnonymous = null;
      switch (tableName)
      {
         case   "QuarryCats" : myAnonymous = _db.QuarryCats.ToList();
         break;
      }
      foreach (var item in myAnonymous )
      {
         // ..           
      }
      

      另一件事是,如果集合中的对象实现一些通用接口会容易得多,因此myAnonymous 可以是像IList&lt;ISomeCommonInterface&gt; 这样的通用集合。

      也就是说,在我看来,在这里使用var 太麻烦了。

      【讨论】:

        【解决方案4】:

        如果您不确定变量的类型,则可以将其定义为dynamic。但是你不能使用 Intellisense,这是一个缺点。

        dynamic myAnonymous;
        

        之后,您可以分配任何您想要的 myAnonymous。它将在运行时初始化。

        【讨论】:

        • 这是解决所有类型系统问题的原子弹解决方案。在这种情况下,我不建议使用动态。
        • tnx 但想要循环遍历它
        • 你可以循环浏览它,只要确保你写的属性名正确
        • @usr 你是对的,但你有其他解决方案吗?
        • @Selman22 我会静态声明类型或以某种方式重构函数。
        【解决方案5】:
        IEnumerable myAnonymous = new object[]{};
        

        循环中:

        foreach(var item in myAnonymous) {
             var cat = item as QuarryCat;
             if(cat != null) {
                 cat.property = "something new";
             }
        }
        

        或者,如果您的类型具有通用字段的接口:

        IEnumerable<IAnimal> myAnonymous = new IAnimal[]{};
        

        循环中:

        foreach(var animal in myAnonymous) {
            animal.eyeColor = "blue";
        }
        

        【讨论】:

        • 亲爱的@Hallvar Helleseth,是的,这是正确的,但出现了另一个错误!我的所有对象都有 OrderId,例如: Product 和 product cat 和其他一些有 OrderId 。通过定义 ienumrable 类型可以循环但不能分配给它的 fildes
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-25
        • 1970-01-01
        • 2021-08-11
        • 2016-05-12
        相关资源
        最近更新 更多