在尝试捕获中使用匿名类型C#

时间:2019-07-11 11:27:16

标签: c#

我为此苦苦挣扎多年,通常只是按照我的方式编写代码,但这是解决问题的时候了。

我正在声明一个返回新的anon类型的变量,并希望将其放入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”

5 个答案:

答案 0 :(得分:5)

匿名类型是语法糖,可以避免命名。编译器使用匿名类型让您专注于程序要执行的操作。

由于这个原因,如果您最终引用匿名类型,则意味着它不再是匿名的:)只要给它起一个名字,问题就会消失:

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;}
}

答案 1 :(得分:3)

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

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

答案 2 :(得分:0)

您是否尝试过在外部声明一个expando对象?

dynamic dt_stop = new ExpandoObject();

这是一个可以在运行时运行的动态对象

答案 3 :(得分:0)

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

答案 4 :(得分:0)

或使用ValueTuple

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