如何预定义一个包含匿名类型的变量?

发布于 2024-10-20 20:14:23 字数 1114 浏览 0 评论 0原文

在下面的简化示例中,我想在分配结果之前定义它。下面的 linq 查询返回匿名类型的列表。 结果 将从 linq 查询中以 IEnumerable<'a> 的形式出现。但我无法在方法的顶部那样定义它。我想要做的事情可能吗(在.NET 4中)?

            bool large = true;
            var result = new IEnumerable();   //This is wrong

            List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();

            if (large)
            {
                result = from n in numbers
                             where n > 5
                             select new
                             {
                                 value = n
                             };
            }
            else
            {
                result = from n in numbers
                             where n < 5
                             select new
                             {
                                 value = n
                             };
            }

            foreach (var num in result)
            {
                Console.WriteLine(num.value);
            }

编辑:要明确的是,我知道在上面的示例中我不需要匿名类型。这只是用一个简单的小例子来说明我的问题。

In the simplified example below I want to define result before it is assinged. The linq queries below return lists of anonymous types. result will come out of the linq queries as an IEnumerable<'a> but I can't define it that way at the top of the method. Is what I am trying to do possible (in .NET 4)?

            bool large = true;
            var result = new IEnumerable();   //This is wrong

            List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();

            if (large)
            {
                result = from n in numbers
                             where n > 5
                             select new
                             {
                                 value = n
                             };
            }
            else
            {
                result = from n in numbers
                             where n < 5
                             select new
                             {
                                 value = n
                             };
            }

            foreach (var num in result)
            {
                Console.WriteLine(num.value);
            }

EDIT: To be clear I know that I do not need anonymous types in the example above. It is just to illustrate my question with a small, simple example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

面如桃花 2024-10-27 20:14:23

匿名类型只能用 var 声明。好处是具有相同属性的匿名类型将是相同的类型。如果你确实需要它(在这个示例中你不需要它)那么你可以写:

var result = Enumerable.Repeat(new {value = 0}, 0); // stub value which will give needed type
if (...)
{
    result = ...;
}
else
{
    result = ...;
}

PS:即使在以前的.Net版本(低于4.0)中也是可能的

Anonymous types can be declared only with var. The good thing is that anonymous types with same properties will be the same types. If you really need it (in this sample you don't need it) then you can write:

var result = Enumerable.Repeat(new {value = 0}, 0); // stub value which will give needed type
if (...)
{
    result = ...;
}
else
{
    result = ...;
}

P.S.: this was possible even in previous .Net version (lower than 4.0)

败给现实 2024-10-27 20:14:23

您可以将其设为 IEnumerable 并只需在查询中选择“n”,而不是创建匿名类型。 EG:

IEnumerable<int> result = null;

result = from n in numbers
         where n > 5
         select n;

如果您实际执行的操作需要匿名类型,那么——由于您使用的是 C# 4——您可以声明 IEnumerable; result,其余代码将正常工作。

You can make it an IEnumerable and just select 'n' in your queries, rather than create an anonymous type. EG:

IEnumerable<int> result = null;

result = from n in numbers
         where n > 5
         select n;

If what you're actually doing requires an anonymous type, then--since you're using C# 4--you can declare IEnumerable<dynamic> result, and the rest of your code will work.

浅浅 2024-10-27 20:14:23

如果您确实必须这样做,我喜欢Snowbear在这里的回答...但就我个人而言,我至少尝试避免陷入这种情况。例如,即使保留匿名类型,我也会将您的原始代码更改为:

bool large = true;
var result = new IEnumerable();   //This is wrong

List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();

Func<int, bool> predicate = large ? new Func<int, bool>(x => x > 5)
                                  : x => x < 5;
var result = numbers.Where(predicate)
                    .Select(x => new { value = x });

foreach (var num in result)
{
    Console.WriteLine(num.value);
}

注意这是如何删除重复的 - 更清楚的是唯一large< /code> 影响 是谓词。

我发现如果变量只分配一个值(最好是在声明时),代码最终会更清晰。

显然这并不总是可行,但在可能的情况下值得记住。在不可能的情况下,Snowbear 的答案很好并且保证有效。

I like Snowbear's answer here if you actually have to do this... but personally I would at least try to avoid getting into this situation. For example, even keeping the anonymous types, I would change your original code to:

bool large = true;
var result = new IEnumerable();   //This is wrong

List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();

Func<int, bool> predicate = large ? new Func<int, bool>(x => x > 5)
                                  : x => x < 5;
var result = numbers.Where(predicate)
                    .Select(x => new { value = x });

foreach (var num in result)
{
    Console.WriteLine(num.value);
}

Note how this has removed duplication - it's clearer that the only thing that large affects is the predicate.

I find that code ends up being clearer if variables are only assigned a single value, ideally at the point of declaration.

Obviously this isn't always feasible, but it's worth bearing in mind where possible. Where it's not possible, Snowbear's answer is fine and guaranteed to work.

梦与时光遇 2024-10-27 20:14:23

您必须事先定义类型。例如

public class TheNumber
{
  public int Number { get; set; }
}

....

IEnumerable<TheNumber> result;
result = numbers.Where(n => n > 5).Select(n => new TheNumber() { Number = n });

You have to define the type beforehand. E.g.

public class TheNumber
{
  public int Number { get; set; }
}

....

IEnumerable<TheNumber> result;
result = numbers.Where(n => n > 5).Select(n => new TheNumber() { Number = n });
明媚殇 2024-10-27 20:14:23

如果在创建匿名类型后不需要任何条件部分,则可以分段构建 LINQ 查询。否则,定义一个新的结构/类来代替匿名类型可能是更明智的选择。

bool large = true;
List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();

IEnumerable<int> query;
if (large) {
    query = query.Where(n => n > 5);
} else {
    query = query.Where(n => n < 5);
}

var result = query.Select(n => new { Value = n });

foreach (var num in result) {
    Console.WriteLine(num.Value);
}

You could build the LINQ query in parts if you do not need any conditional parts after creating the anonymous type. Otherwise it is probably wiser to define a new struct/class to be used in place of anonymous type.

bool large = true;
List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();

IEnumerable<int> query;
if (large) {
    query = query.Where(n => n > 5);
} else {
    query = query.Where(n => n < 5);
}

var result = query.Select(n => new { Value = n });

foreach (var num in result) {
    Console.WriteLine(num.Value);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文