0

私は非常によく似た機能を持っていますが、以前のレポートと他の将来のレポートは 1 つだけですが、どのように最適化して美しく書くことができますか?

public bool AnyPreviousReportByGroup(int groupID)
        {
            if(this.GroupID == groupID)
            {
                return true;
            }
            else
            {
                return PreviousReport.AnyPreviousReportByGroup(groupID);
            }
        }

        public bool AnyNextReportByGroup(int groupID)
        {

            if (this.GroupID == groupID)
            {
                return true;
            }
            else
            {
                return NextReport.AnyNextReportByGroup(groupID);
            }
        }
4

5 に答える 5

1

次のコードは、同じことを実現するためのより簡潔な方法です。

public bool AnyPreviousReportByGroup(int groupID)
{
    return this.GroupID == groupID ||
           this.PreviousReport != null &&
           this.PreviousReport.AnyPreviousReportByGroup(groupID);
}

本当にラムダ式を使用したい場合は、次の方法が考えられます。

public bool AnyReportByGroup(int groupID, Func<Report, Report> getOtherReport)
{
    if (this.GroupID == groupID)
        return true;

    Report other = getOtherReport(this);
    return other != null &&
           other.AnyReportByGroup(groupID, getOtherReport);
}

次に、ラムダ式を使用してこのヘルパー メソッドを呼び出すことができます。

bool anyPrevious = this.AnyReportByGroup(groupID, report => report.PreviousReport);
bool anyNext = this.AnyReportByGroup(groupID, report => report.NextReport);
于 2012-11-20T10:50:08.160 に答える
1
private bool AnyReportByGroup(int groupID, Func<int, bool> callback)
{

    if (this.GroupID == groupID)
    {
        return true;
    }
    else
    {
        return callback(groupID);
    }
}

public bool AnyPreviousReportByGroup(int groupID)
{
    return AnyReportByGroup(groupID, gid => PreviousReport.AnyPreviousReportByGroup(gid));
}

public bool AnyNextReportByGroup(int groupID)
{
    return AnyReportByGroup(groupID, gid => NextReport.AnyNextReportByGroup(gid));
}

しかし、これらのメソッドが単なるサンプルであり、実際のコードではより複雑であることを願っています。
そうでなければ、何を最適化しようとしているのか理解できません。

于 2012-11-20T10:56:07.627 に答える
0

リンクされたリストをトラバースする標準的な方法は次のとおりです。

    public bool AnyPreviousReportByGroup(int groupID)
    {
        var item = this;
        do
        {
            if (item.GroupId == groupID)
            {
                return true;
            }
            item = item.PreviousReport;
        } while (item != null);
        return false;
    }

    public bool AnyNextReportByGroup(int groupID)
    {
        var item = this;
        do
        {
            if (item.GroupId == groupID)
            {
                return true;
            }
            item = item.NextReport;
        } while (item != null);
        return false;
    }

これには、再帰的アプローチのように潜在的に大規模なコール スタックが作成されないという利点があります。

これにより、false が返されず、単に NPE になるコードも修正されます。

これで、リクエストどおりにリファクタリングできます。

    private bool AnyReportByGroup(int groupID, bool searchForward)
    {
        var item = this;
        do
        {
            if (item.GroupId == groupID)
            {
                return true;
            }
            item = searchForward ? item.NextReport : item.PreviousReport;
        } while (item != null);
        return false;
    }

    public bool AnyPreviousReportByGroup(int groupID)
    {
        return AnyReportByGroup(groupID, false);
    }

    public bool AnyNextReportByGroup(int groupID)
    {
        return AnyReportByGroup(groupID, true);
    }
于 2012-11-20T11:11:04.343 に答える
0

falseレポートがなくなったときに戻りたいと仮定した場合の非再帰的なソリューションを次に示します。

public bool AnyPreviousReportByGroup(int groupID)
{
    return GetEventualValue(groupID, r => r.PreviousReport);
}

public bool AnyNextReportByGroup(int groupID)
{
    return GetEventualValue(groupID, r => r.NextReport);
}

public bool GetEventualValue(int groupID, Func<Report, Report> nextReport)
{
    Report report = this;
    while (report != null && report.GroupID != groupID)
    {
        report = nextReport(report);
    }
    return report != null;
}
于 2012-11-20T11:13:49.110 に答える
0

こんな感じかも

public enum ReportType{ Next, Previous }

public bool AnyReportByGroup(int groupID, ReportType type)
{
  if(this.GroupID == groupID)
      return true;
  else
  {
      switch(type)
      {
          case ReportType.Next:
            return NextReport.AnyNextReportByGroup(groupID);
          case ReportType.Previous:
            return NextReport.AnyPreviousReportByGroup(groupID);
      }
      return false;
  }
}
于 2012-11-20T10:51:36.677 に答える