返回多个对象并枚举它

时间:2011-09-15 19:14:11

标签: c#

我有一个返回WorkInfo对象的方法。它有2个属性CompanyNameWorkLocation

一个人可能在多家公司工作过。在这种情况下,我想

  1. 返回WorkInfo对象

  2. 的数组
  3. WorkInfo对象返回给调用方法后,我需要按以下方式对其进行枚举

    foreach(WorkItem wRow in WorkInfo) 
    {
       string s1 = wRow.CompanyName ;
       string s2 = wRow.WorkLocation;
    }
    
  4. 我如何在C#中实现这一目标?

    更新: 我需要做的就是返回一个相同类型的多个对象的集合,并使用ForEach循环遍历它。

    例如,数据表返回一个数据行集合,我们可以使用ForEach(datatable.Rows中的Datarow dr)循环它

    同样,我应该怎么做才能返回一个“WorkInfo”对象的集合,我可以使用ForEach循环它?

8 个答案:

答案 0 :(得分:2)

这是另一次尝试:

注意:快速代码 - 未经测试 - 我使用了您的名称约定(ick 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
  }

}

答案 1 :(得分:1)

你要问这样的伪代码吗?

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;
}

答案 2 :(得分:1)

另一个解决方案,我是最可爱的:),是做这样的事情,伪代码:

 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;
    }

这样做的好处是,通过避免esplisitly实现IEnumerable,你在compialtion期间已经有强大的类型控制,因为你实现了自己的枚举器。

答案 3 :(得分:0)

至少可以说,你想要的设计是错综复杂的。您可以通过实现ad-hoc单链表来实现此目的 - 具有对WorkInfo结构中的下一个WorkInfo的引用。然后返回WorkInfo,其中可能包含或不包含对另一个WorkInfo的引用,依此类推。列表中的最后一项有null。如果你坚持使用IEnumerable循环,那么在WorkInfo中实现foreach()。如果不是,那么枚举可能是以下形式:

for(;wRow != null; wRow = wRow.Next)    
{
    string s1 = wRow.CompanyName; 
    //...
}

免责声明:如果你做了那些令人厌恶的事情,而不是回复一个好的旧WorkInfo集合,那么上帝可能会杀死一只小猫。

答案 4 :(得分:0)

如果我理解正确,您可以使用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%确定这是否是您正在寻找的,但希望它有所帮助,即使只是为了让您思考。

答案 5 :(得分:0)

听起来你的混乱是因为你认为你需要两个功能:

public WorkItem GetCompany(User user) { /* ... */ }

public WorkItem[] GetCompanies(User user) { /* ... */ }

但你不需要两者。您只需编写一个函数来处理这两种情况。

基本上,foreach获取IEnumerable(例如数组,列表,Linq查询的结果),并循环遍历它。

IEnumerable可以枚举零个,一个或多个对象。您可以将此视为包含许多对象的枚举。使用列表或数组,这很有意义。

为了支持只返回一家公司,您只需返回大小为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
    }
}

但除非你真的需要单独的公司/多公司进行不同的处理,否则我建议你完全删除长度检查,然后编写一组代码。这将在以后更容易维护和调试。

答案 6 :(得分:0)

其他人已经表明你可以让你的函数返回一个数组或列表并在其上进行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;
}

答案 7 :(得分:0)

我就是这样做的。

public Tuple<int, int> ReturnMultipleValues()
{
     return new Tuple<int,int>(1,2);
}