简体   繁体   English

在try catch c#中使用匿名类型

[英]Using an anonymous type in a try catch c#

I have struggled with this for years and normally just code my way around it, but it is time to solve it. 多年来我一直在努力解决这个问题,通常只是按照自己的方式编写代码,但现在是时候解决它了。

I am declaring a var that returns a new anon type and want to put it in a try/catch. 我声明一个var,它返回一个新的anon类型,并希望将它放在try / catch中。 However, doing that means it is out of scope and cannot be seen by later code obviously. 但是,这样做意味着它超出了范围,显然不能被后面的代码看到。 Normally I just declare it first, then wrap the code in the try/catch then reassign inside of it like: 通常我只是先声明它,然后将代码包装在try / catch中,然后在其中重新分配,如:

int result = 0;

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

But here is my real code that I cannot figure out how to do something like that: 但这是我的真实代码,我无法弄清楚如何做这样的事情:


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

UPDATE: I do use dt_stop extensively after this, I am wanting to catch if there is a problem with it is assigned data. 更新:我在此之后广泛使用dt_stop,我想要抓住它是否有分配数据的问题。

I created the following class: 我创建了以下类:

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

    public DistributionRouteHeader R { get; set; }
}

Then I attempt to use is like: 然后我尝试使用就像:

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

I am getting Cannot initialize type 'StopData' with a collection initializer because it does not implement 'System.Collections.IEnumerable' 我收到了无法使用集合初始化程序初始化类型'StopData',因为它没有实现'System.Collections.IEnumerable'

Anonymous types are syntactic sugar to avoid you to name them. 匿名类型是语法糖,以避免您命名它们。 Anonymous types are used by the compiler to let you focus on what you want the program do. 编译器使用匿名类型来让您专注于您希望程序执行的操作。

For this reason, if you end up on referencing an anonymous type, it means that it is no longer anonymous:) Just give it a name and your issue goes away: 出于这个原因,如果你最终引用匿名类型,这意味着它不再是匿名的:)只要给它一个名字,你的问题就会消失:

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 can be a System.Tuple or a standard class. MyType可以是System.Tuple或标准类。 To preserve your semantics, you can make it a DTO (fill in your types as I cannot infer them from your source): 要保留您的语义,您可以将其设为DTO(填写您的类型,因为我无法从您的来源推断它们):

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

You can declare a default instance of your anonymous type like: 您可以声明匿名类型的默认实例,如:

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

Have you tried declaring an expando object outside? 你试过在外面声明一个expando对象吗?

dynamic dt_stop = new ExpandoObject();

It's a dynamic object which works at runtime 它是一个在运行时工作的动态对象

The only solution I can think of is using a dynamic type. 我能想到的唯一解决方案是使用动态类型。 So dynamic instead of var. 所以动态而不是var。 But be aware that there's no intellisense on dynamic types. 但请注意,动态类型没有智能感知。

Or use a ValueTuple . 或者使用ValueTuple

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM