创建一个变量来容纳通过
LINQ query
生成的匿名对象列表,同时将变量声明保留在 try/catch
外部并在 try/catch
内部处理赋值的正确方法是什么?
目前我将变量声明为
IEnumerable<object>
,但是当我稍后尝试使用它时,这会导致一些问题......
即
var variableDeclaration;
try
{
// ...
assignment
// ...
}
catch...
编辑:
如果相关(不认为相关),则对象列表将作为 MVC3 操作的
Json
结果返回。 我正在尝试减少一些 using
语句在数据库中打开的时间,因为我遇到了一些性能问题,我正在尝试解决一些问题。 在进行一些测试时,我遇到了这个问题,但似乎找不到有关它的信息。
编辑2:
如果我可以要求避免关注
LINQ
。 虽然使用 LINQ,但问题更具体于与 Anonymous
对象相关的范围问题。 事实上,(在本例中)使用 LINQ 来生成它们。
此外,一些答案提到了
dynamic
的使用,虽然这将编译它,但不允许我稍后在该方法中使用。 如果我想做的事情不可能,那么目前的答案似乎是使用我需要的定义创建一个新的 class
并使用它。
可以通过创建一个通用的
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
好吧,如果您使用 LINQ,则除非具体化,否则不会评估查询...
所以,您也许能够:
var myQuery = //blah
try
{
myQuery = myQuery.ToList(); //or other materializing call
}
catch
{
}
你也许可以不用使用
dynamic
??
dynamic variableDeclaration;
try
{
variableDeclaration = SomeList.Where(This => This == That);
}
catch { }
不确定这会进一步影响您的代码块,但这只是一个想法:)
如果您在像 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)
另一个作弊:您可以在本地定义变量(类似于 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内部返回数据,并在外部第二次返回默认信息。
这让我烦恼了一段时间。最后,我构建了一些通用辅助方法,我可以在其中传递生成匿名对象的代码,并将捕获代码作为 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;
}
);