在此示例中,LINQ ToArray 可以返回强类型数组吗?

发布于 2024-12-07 13:41:50 字数 1073 浏览 1 评论 0原文

我设计这个例子是因为它是我试图解决的实际问题的一个易于理解的版本。这是类及其关系。

首先,我们有一个 Country 类,其中包含由字符串索引的 State 对象字典(例如其名称或缩写)。 State 类的内容是无关紧要的:

class Country
{
    Dictionary<string, State> states;
}

class State { ... }

我们还有一个 Company 类,其中包含零个或多个 BranchOffice 对象的字典,也按州名称或缩写进行索引。

class Company
{
    Dictionary<string, BranchOffice> branches;
}

class BranchOffice { ... }

我们正在使用的实例是一个 Country 对象和一组 Company 对象:

Country usa;
Company companies[];

我想要的是一组包含分支的 State 对象。我写的LINQ如下。首先,它获取所有实际包含分支机构的公司,然后通过比较两个列表的键来加入州列表。

问题在于 ToArray 返回匿名类型。我明白为什么匿名类型不能转换为强类型。我试图弄清楚是否可以更改某些内容以取回强类型数组。 (并且我愿意接受有关编写 LINQ 整体的更好方法的建议。)

我尝试过在所有地方(在前面、在 list2、在最终选择以及其他不太可能的候选者)投射到 BranchOffice。

BranchOffice[] offices =
(from cm in companies
 where cm.branches.Count > 0
 select new {
        list2 = 
        (from br in cm.branches
         join st in usa.states on br.Key equals st.Key
         select st.Value
        )
 }
).ToArray();

I've contrived this example because it's an easily digested version of the actual problem I'm trying to solve. Here are the classes and their relationships.

First we have a Country class that contains a Dictionary of State objects indexed by a string (their name or abbreviation for example). The contents of the State class are irrelevant:

class Country
{
    Dictionary<string, State> states;
}

class State { ... }

We also have a Company class which contains a Dictionary of zero or more BranchOffice objects also indexed by state names or abbreviations.

class Company
{
    Dictionary<string, BranchOffice> branches;
}

class BranchOffice { ... }

The instances we're working with are one Country object and an array of Company objects:

Country usa;
Company companies[];

What I want is an array of the State objects which contain a branch. The LINQ I wrote is below. First it grabs all the companies which actually contain a branch, then joins to the list of states by comparing the keys of both lists.

The problem is that ToArray returns an anonymous type. I understand why anonymous types can't be cast to strong types. I'm trying to figure out whether I could change something to get back a strongly typed array. (And I'm open to suggestions about better ways to write the LINQ overall.)

I've tried casting to BranchOffice all over the place (up front, at list2, at the final select, and other less-likely candidates).

BranchOffice[] offices =
(from cm in companies
 where cm.branches.Count > 0
 select new {
        list2 = 
        (from br in cm.branches
         join st in usa.states on br.Key equals st.Key
         select st.Value
        )
 }
).ToArray();

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

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

发布评论

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

评论(2

去了角落 2024-12-14 13:41:50

您可以执行以下操作:

 select new MyClassOfSomeType {
   ..
)

对于选择,您可以为其指定自定义类类型。然后您还可以使用 ToList。使用 ArrayList,如果需要保持松散类型,则可以稍后使用 Cast<> 将其设置为强类型,但仅适用于不生成匿名类的任何选择结果。

HTH。

You can do:

 select new MyClassOfSomeType {
   ..
)

For selection, you can give it a custom class type. You can also then use ToList. With ArrayList, if you need to keep it loosely typed, you can then make it strongly typed later using Cast<>, though only for any select result that doesn't generate an anonymous class.

HTH.

你的背包 2024-12-14 13:41:50

如果我正确地理解了这个问题,那么您只需要有办事处分支机构的州,而不是分支机构。如果是这样,一个可能的 linq 如下:

State[] offices =
(from cm in companies
 where cm.branches.Count > 0
 from br in cm.branches
 join st in usa.states on br.Key equals st.Key
 select st.Value
).Distinct().ToArray();

如果您想要状态和分支,那么您将必须执行 group by,结果将是 IEnumerable>,您可以在之后进行处理。

var statesAndBranches =
from cm in companies
where cm.branches.Count > 0
from br in cm.branches
join st in usa.states on br.Key equals st.Key
group br.Value by st.Value into g
select g;

还有一件事,即使您将国家和分支机构声明为字典,它们也被用作 IEnumerable(来自字典中的 keyValuePair),因此您不会从它们中获得任何性能优势。

If i understand the problem correctly, the you want just the states that have office brances in them, not the branches too. If so, one posible linq is the following:

State[] offices =
(from cm in companies
 where cm.branches.Count > 0
 from br in cm.branches
 join st in usa.states on br.Key equals st.Key
 select st.Value
).Distinct().ToArray();

If you want both the states and the branches, then you will have to do a group by, and the result will be an IEnumerable>, which you can process after.

var statesAndBranches =
from cm in companies
where cm.branches.Count > 0
from br in cm.branches
join st in usa.states on br.Key equals st.Key
group br.Value by st.Value into g
select g;

Just one more thing, even though you have countries and branches declared as dictionaries, they are used as IEnumerable (from keyValuePair in dictionary) so you will not get any perf benefit form them.

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