返回多个对象并对其进行枚举
本文关键字:枚举 对象 返回 | 更新日期: 2023-09-27 18:08:38
我有一个返回WorkInfo
对象的方法。它有两个性质:CompanyName
和WorkLocation
。
一个人可能在多家公司工作过。在本例中,我想
-
返回
WorkInfo
对象的数组 -
在
WorkInfo
对象返回给调用方法后,我需要按以下方式枚举它foreach(WorkItem wRow in WorkInfo) { string s1 = wRow.CompanyName ; string s2 = wRow.WorkLocation; }
如何在c#中实现这一点?
更新:我所需要做的就是返回相同类型的多个对象的集合,并使用ForEach循环遍历它。
一个数据表返回一个数据表的集合,我们可以使用ForEach(Datarow dr in datatable. rows)来遍历它
同样,我应该做什么来返回一个"WorkInfo"对象的集合,我可以使用ForEach循环?
这是另一个尝试:
注释:快速代码-未经测试-我使用了您的名称约定(如CamelCase)等
public class WorkInfo
{
public string CompanyName { Get; Set; };
public string WorkLocation { Get; Set; };
}
public class Example
{
public List<WorkInfo> GetAList()
{
List<WorkInfo> result = new List<WorkInfo>();
result.Add(new WorkInfo { CompanyName = "MS", WorkLocation = "Redmond" });
result.Add(new WorkInfo { CompanyName = "Google", WorkLocation = "New York" });
result.Add(new WorkInfo { CompanyName = "Facebook", WorkLocation = "CA" });
return result;
}
public UseAList()
{
foreach(WorkInfo wRow in GetAList())
{
string s1 = wRow.CompanyName ;
string s2 = wRow.WorkLocation;
// process list elements s1 and s2
}
}
}
下面是一些代码,我相信可以解决你的问题:
workInfo = FunctionThatReturnsArray(..);
if (workInfo.Length == 1)
{
// process single item at workInfo[0]
}
else
{
foreach(WorkItem wRow in WorkInfo)
{
string s1 = wRow.CompanyName ;
string s2 = wRow.WorkLocation;
// process list elements s1 and s2
}
}
你想要这样的伪代码吗?
public WorkItem[] GetWorkItems(Person p)
{
WorkItem[] result = YourDatabaseLogicOrBusinessLogic.GetWorkItems(p);
return result;
}
然后:
foreach(WorkItem wRow in GetWorkItems(p1))
{
string s1 = wRow.CompanyName ;
string s2 = wRow.WorkLocation;
}
另一个解决方案,对我来说是最可爱的:),是做这样的东西,伪代码:
public class WorkInfoEnumerator
{
List<WorkItem > wilist= null;
int currentIndex = -1;
public MyClassEnumerator(List<WorkItem > list)
{
wilist= list;
}
public WorkItem Current
{
get
{
return wilist[currentIndex];
}
}
public bool MoveNext()
{
++currentIndex;
if (currentIndex < wilist.Count)
return true;
return false;
}
}
public class WorkInfo
{
List<WorkItem > mydata = new List<WorkItem >() {.... }; //init here, for example
public WorkInfoEnumerator GetEnumerator()
{
return new WorkInfoEnumerator(mydata);
}
}
,在代码的某个地方写正好是你想要的:
foreach(WorkItem wRow in WorkInfo)
{
string s1 = wRow.CompanyName ;
string s2 = wRow.WorkLocation;
}
这样做的美妙之处在于,通过避免明确地实现IEnumerable,您在竞争期间已经具有了强类型控制,因为您实现了自己的枚举器
您想要的设计至少可以说是令人费解的。您可以通过实现一个特别的单链表来实现这一点——在WorkInfo结构中有一个对下一个WorkInfo的引用。然后返回一个WorkInfo
,它可能包含也可能不包含对另一个WorkInfo的引用,以此类推。列表中的最后一项具有null
。然后在WorkInfo中实现IEnumerable
,如果你坚持使用foreach()
循环。如果不是,则枚举的形式可能为:
for(;wRow != null; wRow = wRow.Next)
{
string s1 = wRow.CompanyName;
//...
}
免责声明:如果你做了那件令人讨厌的事,而不是返回一个很好的旧WorkInfo
集合,上帝可能会杀死一只小猫。
如果我理解正确,您可以使用linq查询做您正在做的事情。这不是测试,所以不要恨我:)
...Get all workinfos for person and iterate over them,
...grouping by company name.
...Assuming you have an object called workInfos that contains
...the data returned from your datastore.
List<WorkInfo> result = new List<WorkInfo>();
result = (from wi in workInfos
group wi on wi.CompanyName into gwi
select new WorkInfo {
CompanyName = gwi.Key,
Location = gwi.Location
}).ToList();
不能100%确定这是否是你正在寻找的,但希望它能帮助,即使只是为了让你思考。
听起来你的困惑是因为你认为你需要两个函数:
public WorkItem GetCompany(User user) { /* ... */ }
和
public WorkItem[] GetCompanies(User user) { /* ... */ }
但是你不需要两者都需要。你可以只写一个函数来处理这两种情况。
基本上,foreach
接受IEnumerable
(例如数组,列表,Linq查询的结果),并循环它。
IEnumerable
可以枚举0、1或多个对象。你可以把它想象成包含这么多对象的枚举。对于列表或数组,这很有意义。
为了支持只返回单个公司,您可以只返回大小为1的IEnumerable
(列表或数组)。
public WorkItem[] GetCompanies(User user)
{
// Todo: some DB query here
// if we get 5 results, return them as an array of size 5
// If we get one result, return it as an array of size 1
}
如果您需要代码处理函数只返回单个结果的特殊情况,则只需检查.Count
或.Length
成员。
WorkItem[] result = GetCompanies(user);
if(result.Length == 0)
{
// todo: is this an error? If so, let the user know here
}
else if(result.Length == 1)
{
WorkItem theOnlyCompany = result[0];
// todo: do something interesting here, for the 1-company case
}
else
{
foreach(WorkItem in result)
{
// todo: do something interesting here, for the multi-company case
}
}
但是,除非您真的需要对单个公司/多个公司进行区别对待,否则我建议您完全取消长度检查,只编写一组代码。
其他人已经表明,您可以让您的函数返回一个数组或列表并对其进行foreach。如果只有一个条目,它也会工作得很好。
如果您必须一次检索一个,您也可以自己实现枚举逻辑:
public IEnumerable<WorkItem> WorkItems(Person p)
{
WorkItem item = GetAWorkItem(p);
yield result item;
}
:
foreach(WorkItem item in WorkItems())
{
string s1 = item.CompanyName;
string s2 = item.WorkLocation;
}
我是这样做的。
public Tuple<int, int> ReturnMultipleValues()
{
return new Tuple<int,int>(1,2);
}