【问题标题】:Using an anonymous type in a try catch c#在 try catch c# 中使用匿名类型
【发布时间】:2019-07-11 20:35:09
【问题描述】:

多年来我一直在为此苦苦挣扎,通常只是编写代码解决它,但现在是时候解决它了。

我正在声明一个返回新匿名类型的 var,并希望将其放入 try/catch 中。 但是,这样做意味着它超出了范围,以后的代码显然无法看到。 通常我只是先声明它,然后将代码包装在 try/catch 中,然后在其中重新分配,例如:

int result = 0;

try
{
    result = 77; //real code goes here
}
catch (Exception)
{
    throw;
}

但这是我的真实代码,我无法弄清楚如何做这样的事情:


    try
    {
        var dt_stop = (from s in cDb.DistributionStopInformations
                       join r in cDb.DistributionRouteHeaders on s.RouteCode equals r.RouteCode
                       where r.RouteDate == s.RouteDate &&
                       r.BranchId == s.BranchId &&
                       (r.CompanyNo == companyNo && s.CompanyNo == companyNo)
                       && s.UniqueIdNo == uniqueId

                       select new
                       {
                           s,
                           r
                       }).Single();
    }
    catch (Exception)
    { //no this will not be blank
        throw;
    }

更新: 在此之后我确实广泛使用 dt_stop,如果分配数据有问题,我想了解一下。

我创建了以下类:

 public class StopData
{
    public DistributionStopInformation S { get; set; }

    public DistributionRouteHeader R { get; set; }
}

然后我尝试使用是这样的:

 StopData dt_stop = null;

        try
        {
            dt_stop = (from S in cDb.DistributionStopInformations
                       join R in cDb.DistributionRouteHeaders on S.RouteCode equals R.RouteCode
                       where R.RouteDate == S.RouteDate &&
                       R.BranchId == S.BranchId &&
                       (R.CompanyNo == companyNo && S.CompanyNo == companyNo)
                       && S.UniqueIdNo == uniqueId

                       select new StopData
                       {
                           S,
                           R
                       }).Single();

        }
        catch (Exception)
        {
            //YES....THERE WILL BE CODE HERE
            throw;
        }

我得到 无法使用集合初始化程序初始化类型“StopData”,因为它没有实现“System.Collections.IEnumerable”

【问题讨论】:

  • 实际上有一个catch块,除了抛出什么都不做吗?如果是这样,我强烈建议将其完全删除。
  • 如果dt_stop 只填充了try/catch 内的数据,那以后为什么还要使用呢?你会冒NullReferenceException的风险
  • 你可以在尝试之前声明一个动态变量,然后再使用它
  • 匿名对象与使用它的代码紧密耦合,因此您可以将该代码放在 try catch 块中。如果世代和用途如此不同以至于它们应该分开,则表明您应该定义一种类型(正如许多答案所暗示的那样)
  • @JonSkeet - 不,它会被填写

标签: c#


【解决方案1】:

匿名类型是避免你命名它们的语法糖。编译器使用匿名类型让您专注于您希望程序执行的操作。

因此,如果您最终引用了匿名类型,则意味着它不再是匿名的:) 只需给它一个名称,您的问题就会消失:

MyType dt_stop = null;
try
{
   dt_stop = (from s in cDb.DistributionStopInformations
                  join r in cDb.DistributionRouteHeaders on s.RouteCode equals r.RouteCode
                  where r.RouteDate == s.RouteDate &&
                  r.BranchId == s.BranchId &&
                  (r.CompanyNo == companyNo && s.CompanyNo == companyNo)
                  && s.UniqueIdNo == uniqueId

                  select new MyType
                  {
                      s,
                      r
                  }).Single();
}
catch (Exception)
{
   // here dt_stop can be used
   throw;
}

MyType 可以是 System.Tuple 或标准类。为了保留您的语义,您可以将其设为 DTO(填写您的类型,因为我无法从您的来源推断它们):

internal sealed class MyType
{
    public <The type of s> S {get; set;}
    public <The type of r> R {get; set;}
}

【讨论】:

  • 我做了更改,但做错了...请稍等。
  • 好的...进展得更远了,但还没有完全达到。
  • 好吧,你能不能试着改变你的类型以使用构造函数并在那里初始化参数。它应该可以工作,但我现在无法测试它。
  • 这就是我要尝试做的事情,我开始尝试但没时间了。我将不得不回到它。
【解决方案2】:

您可以声明匿名类型的默认实例,例如:

var temp = new {A = default(int), B = default(int)};
try
{
    temp = new  {A= 1, B=2};
}
catch (Exception)
{
}

【讨论】:

    【解决方案3】:

    你试过在外面声明一个 expando 对象吗?

    dynamic dt_stop = new ExpandoObject();
    

    这是一个在运行时工作的动态对象

    【讨论】:

      【解决方案4】:

      我能想到的唯一解决方案是使用动态类型。所以动态而不是var。但请注意,动态类型没有智能感知。

      【讨论】:

      • 布鲁诺的回答在这里创建另一个匿名类型的实例很好。
      • 抱歉,我回复后看到了(我们同时回复了)。
      【解决方案5】:

      或者使用ValueTuple

      var thing = default((int S, int R));
      try
      {
          thing = /*..*/.Select((s, r));
      }
      catch (Exception)
      {
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-26
        • 2012-11-25
        • 2010-10-31
        相关资源
        最近更新 更多