匿名类型范围问题

问题描述 投票:0回答:6

创建一个变量来容纳通过

LINQ query
生成的匿名对象列表,同时将变量声明保留在
try/catch
外部并在
try/catch
内部处理赋值的正确方法是什么?

目前我将变量声明为

IEnumerable<object>
,但是当我稍后尝试使用它时,这会导致一些问题......

var variableDeclaration;

try 
{
    // ...
    assignment
    // ...
}
catch...

编辑:

如果相关(不认为相关),则对象列表将作为 MVC3 操作的

Json
结果返回。 我正在尝试减少一些
using
语句在数据库中打开的时间,因为我遇到了一些性能问题,我正在尝试解决一些问题。 在进行一些测试时,我遇到了这个问题,但似乎找不到有关它的信息。

编辑2:

如果我可以要求避免关注

LINQ
。 虽然使用 LINQ,但问题更具体于与
Anonymous
对象相关的范围问题。 事实上,(在本例中)使用 LINQ 来生成它们。

此外,一些答案提到了

dynamic
的使用,虽然这将编译它,但不允许我稍后在该方法中使用。 如果我想做的事情不可能,那么目前的答案似乎是使用我需要的定义创建一个新的
class
并使用它。

c# scope anonymous-objects
6个回答
4
投票

可以通过创建一个通用的

Cast
方法来解决这个问题,如 Jon Skeet here 所概述。它会起作用并为您提供您想要的智能感知。但是,此时,为 linq 方法创建自定义类型有什么问题吗?

public class MyClass
{
    public int MyInt { get; set; }
}

IEnumerable<MyClass> myClass = 
    //Some Linq query that returns a collection of MyClass

4
投票

好吧,如果您使用 LINQ,则除非具体化,否则不会评估查询...

所以,您也许能够:

var myQuery = //blah
try
{
    myQuery = myQuery.ToList();  //or other materializing call
}
catch
{
}

1
投票

你也许可以不用使用

dynamic
??

     dynamic variableDeclaration;
     try
     {
         variableDeclaration = SomeList.Where(This => This == That);
     }
     catch { }

不确定这会进一步影响您的代码块,但这只是一个想法:)


1
投票

如果您在像 try/catch 一样使用变量之前声明变量,则不能使用 [var],因为它是预期的。相反,您必须输入变量。

var x = 0;
try{
   x = SomethingReturningAnInt();
}

int x;
try{
   x = SomethingReturningAnInt();
}

但是在您的情况下,您并不真正“知道”该方法返回什么

var x = ...;
try{
   x = Something();
}
catch{}

不起作用

当您事先不知道类型时,您可以选择使用动态:

dynamic x;
try{
   x = Something();
}
catch{}

(但这感觉就像回到VB4)


1
投票

另一个作弊:您可以在本地定义变量(类似于 Jon 在 Dave Zych 答案中的 hack),然后在 try/catch 中使用它。只要您可以在 try-catch 之前创建相同的匿名项类型就可以了(因为具有相同字段名称和类型的匿名类型被认为是相同的):

var myAnonymouslyType = Enumerable.Repeat(
    new {Field1 = (int)1, Field2 = (string)"fake"}, 0);

try 
{ 
   myAnonymouslyType = ...(item => 
     new {Field1 = item.Id, Field2=item.Text})...
}
...

这是比 Jon 在函数之间对匿名类型进行转换更安全的选择,因为如果类型不匹配,编译器会立即发现错误。

注意:如果你必须走这条路,我会投票给非匿名类型......

注2:根据您的实际需要,考虑简单地从try/catch内部返回数据,并在外部第二次返回默认信息。


1
投票

这让我烦恼了一段时间。最后,我构建了一些通用辅助方法,我可以在其中传递生成匿名对象的代码,并将捕获代码作为 lamdas,如下所示

public static class TryCatch
{
    public static T Expression<T>(Func<T> lamda, Action<Exception> onException)
    {
        try
        {
            return lamda();
        }
        catch(Exception e)
        {
            onException(e);
            return default(T);
        }            
    }

}

//and example

Exception throwexception = null;
        var results = TryCatch.Expression(
            //TRY
            () => 
                {
                    //simulate exception happening sometimes.
                    if (new Random().Next(3) == 2)
                    {
                        throw new Exception("test this");
                    }
                    //return an anonymous object
                    return new { a = 1, b = 2 };
                } ,
            //CATCH
            (e) => { throwexception = e;                         
                     //retrow if you wish
                     //throw e;
                   }
            );

https://gist.github.com/klumsy/6287279

© www.soinside.com 2019 - 2024. All rights reserved.