我知道不允许将nonymous类型设置为null,但是我该如何解决这个问题:
var products = null; //this cant be null, but somehow it must be declared in this outer scope, and not only inside the try-catch scope
try
{
products = (from p in repository.Products
select new { p.Product, p.ProductName }).ToList();
}
catch (Exception e)
{
return;
}
Console.WriteLine(products.FirstOrDefault().ProductName)
答案 0 :(得分:11)
我同意其他答案,您应该考虑重构此代码或使用名义类型而不是匿名类型。
但是,有一种方法可以在匿名类型的变量中获取空引用。这很容易。
static List<T> GimmeANullListOf<T>(T t) { return (List<T>)null; }
...
var products = GimmeANullListOf(new { X = 1, Y = "hello" });
这个技巧被称为“通过示例施放”,它很奇怪但合法。
答案 1 :(得分:5)
或new Nullable<bool>()
可以很好地完成工作。
答案 2 :(得分:2)
对于那些简单的事情以及您return
例外的事实,您应该能够在try
块中执行所有操作,而不必在其外部声明products
:
try
{
var products = (from p in repository.Products
select new { p.Product, p.ProductName }).ToList();
Console.WriteLine(products.FirstOrDefault().ProductName);
}
catch (Exception e)
{
return;
}
虽然我非常同意SLaks,但你不应该吞下异常并像那样返回。
答案 3 :(得分:2)
没有简单的方法。您的选择要么是更改控制流以将整个事物包装在try{}
块中(在这种情况下是微不足道的,但我假设此代码是为了说明目的而简化),或者声明一个具体类型,例如
class ProductWithName
{
public int Product;
public string ProductName;
}
然后使用
List<ProductWithName> products = null;
和
select new ProductWithName { Product = p.Product, ProductName = p.ProductName }
哪种选择最好取决于你的真实代码是什么样的。
答案 4 :(得分:1)
这不是匿名类型,不能为null,它是IEnumerable<T>
(或IQueryable),因为你迭代它所以不能为空。
您可以使用products ?? Enumerable.Empty<Product>()
将null替换为空IEnumerable<T>
。
不要吞下这样的例外。在非常具体的场景中捕获Exception
基类只是一个好主意,而你的基类不是其中之一。
答案 5 :(得分:1)
你想要的是在声明范围之外使用匿名类型。
你可以用反射来做到这一点:
IEnumerable<object> products = null;
// ...
var anon = products.FirstOrDefault();
Console.WriteLine(anon.GetType().GetProperty("ProductName").GetValue(anon, null));
或动态:
IEnumerable<dynamic> products = null;
// ...
var anon = products.FirstOrDefault();
Console.WriteLine(anon.ProductName);
答案 6 :(得分:0)
由于LINQ延迟执行,您可以在父作用域中定义查询并在try catch块中运行它,如下所示:
var productsDB = new List<Func<string>>() { () => "Apples", () => "Pears", () => "Bannanas" };//, () => { throw new NotImplementedException(); } }; // sorry, couldn't think of a better way to make this fail in 2 mins..
var products = (
from p in productsDB
select new
{
Name = p()
} );
try
{
products.ToList(); // runs the LINQ query
products.Dump(); // prints the results (LINQPad)
}
catch { "there was an error".Dump(); }
或者另一个选项是Tuple类,它非常适合这种事情:
var productsDB = new[] { "Apples", "Pears", "Bannanas" };
List<Tuple<string>> products;
try
{
products = (
from p in productsDB
select Tuple.Create( p ) ).ToList();
products.Dump();
}
catch { "there was an error".Dump(); }
// Build anonymous type from (read-only) Tuple here if necessary...
编辑:刚刚意识到我误读了帖子:p - 继承我原来的帖子:
我认为只是类型检查员抱怨,尝试这样的事情......
var employees = (
from person in db.denormalisedPeople
where person.Type == "employee"
select new
{
name = employee.FullName,
areaID = new Nullable<int>(), // placeholder.. set in a future query
} ).ToList();
(未经测试的代码,但该技术对我来说很好)