当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - Declaring explicit type instead of var in select statement

问题描述:

I'm doing the following request. It works as supposed to and returns data structured correctly. (It creates an element with "head" corresponding to the common field and puts the all elements of the same value in that field as a an Array in the "tail".)

var result

= from A in As

group A by A.F into B

select new

{

F1 = B.Key,

F2 = from A in As

where A.F == B.Key

select A

};

Now I'd like to declare it's type explicitly. I've checked in the debugger that my assumption on types is correct, however, when I try to declare that, it gives me conversion errors.

  1. Why?
  2. How can I declare the type explicitly?

I've tried different variant of declarations and as but failed.

IEnumerable<Tuple<String, IEnumerable<MyType>>> result

= from ...

} as Tuple<String, MyType>;

I know it's doable but I lack the experience to get it right. I've noticed that the following works. However, I'm not sure how to take it a step further, exchanging Object for the actual variable type.

IEnumerable<Object> result

= from ...

} as Object;

网友答案:

Although you know that the object "insides" are the same, C# is statically typed and resolves types based on their metadata (name, namespace...), not on their members. You select an anonymous type, not a Tuple, so the type resolver cannot "agree" with it being used as a Tuple.

If you hover over the var keyword in Visual Studio, it will tell you what type is it (because it must be known during compile time, unless it's a dynamic). However due to the fact you are using anonymous type, you will not be able to write the type explicitly - it has no name in the C# source code.

What you might do is either define the type elsewhere

internal class MyObj
{
    public MyObj(string head, IEnumerable<Foo> tail)
    {
        Head = head;
        Tail = tail;
    }

    public string Head { get; set; }
    public IEnumerable<Foo> Tail { get; set; }
}

and then use it in your query:

IEnumerable<MyObj> result
  = from A in As
    group A by A.F into B
    select new MyObj(
        B.Key,
        from A in As
        where A.F == B.Key
        select A);

or use a Tuple as Jon suggested here.

网友答案:

The type of the enumerable sequence produced is determined by the type of the expression after the select clause, so:

select Tuple.Create(
    B.Key,
    (from A in As where A.F == B.Key select A).ToList()
)
网友答案:

Since you're creating an anonymous type with the select new {... } you have to use var. There is no way to express the type explicitly.

网友答案:

Tuple<String, IEnumerable<MyType>> <=> Tuple<String, MyType> this at first, but problem not here, you cant cast anonymous type to Tuple. You must explicitly define type then use it.

public class YourClass
{
    public string F1 {get; set;}
    public IEnumerable<MyType> F2 {get; set;}
} 

IEnumerable<YourClass> result
  = from A in As
    group A by A.F into B
    select new YourClass
    {
      F1 = B.Key,
      F2 = from A in As
           where A.F == B.Key
           select A
    };
网友答案:

You can't explicitly declare the type because by saying

select new {
   Member = Value
}

you're using an anonymous type - such types have unspeakable names and so this is one of the cases where you must use var.

分享给朋友:
您可能感兴趣的文章:
随机阅读: