当前位置:  开发笔记 > 编程语言 > 正文

传递具有两个参数的委托作为参数函数

如何解决《传递具有两个参数的委托作为参数函数》经验,为你挑选了2个好方法。

我有一系列看起来非常相似的函数,但对于一行,如下面两行(但我还有更多):

private static int HowManyHoursInTheFirstYear(IList samples)
{
    DateTime firstDate = samples[0].Date;
    int count = 0;

    while (count < samples.Count && 
          samples[count].Date.Year == firstDate.Year)
    {
        count++;
    }

    return count;
}


private static int HowManyDaysInTheFirstMonth(IList samples)
{
    DateTime firstDate = samples[0].Date;
    int count = 0;

    while (count < samples.Count && 
           samples[count].Date.Month == firstDate.Month) // <--- only change!
        count++;
    }

    return count;
}

我正在考虑使用委托以一种优雅的方式删除代码中的重复,这将允许我调用类似的东西:

HowManyDaysInTheFirstPeriod(
    samples,
    delegate(DateTime d1, DateTime d2) { return d1.Month == d2.Month; });

从而宣布代表如下:

delegate bool DateComparer(DateTime first, DateTime second);

并且HowManyDaysInTheFirstPeriod应该是以下内容:

private static int HowManySamplesInFirstPeriod
    IList samples,
    DateComparer comparer)
{
    DateTime firstDate = samples[0].Date;
    int count = 0;

    while (count < samples.Count && comparer())
    {
        count++;
    }
}

不幸的是,编译器抱怨比较器需要两个参数.

我对C#比较陌生,在这里遇到了障碍.你怎么解决这个问题?



1> John Feminel..:

你快到了!该comparer委托参数就像任何其他的功能:您仍然需要通过适当的参数来调用它.在你的情况下,这意味着这种变化:

while (count < samples.Count && comparer(samples[count].Date, firstDate))
{
    count++;
}

(另请注意,samples也许应该是samples.Count,正如我上面写的.)



2> jalf..:

你可以做得更简单一些.简单地为函数提供一个委托,它从DateTime中提取应该比较的内容:

private static int HowManySamplesInFirstPeriod
    IList samples,
    Func f // a function which takes a DateTime, and returns some number
{
    DateTime firstDate = samples[0].Date;
    int count = 0;

    while (count < samples && f(samples[count].Date) == f(firstDate))
    {
        count++;
    }
}

然后它可以这样调用:

HowManySamplesInFirstPeriod(samples, (dt) => dt.Year); // to get the year
HowManySamplesInFirstPeriod(samples, (dt) => dt.Month); // to get the month

(dt) => dt.year语法可能是新的给你,但它的写作更清洁的方式"匿名委托这需要一个对象DT一些通用型的,并返回dt.year".你可以写一个老式的代表,但这更好.:)

但是,通过添加另一个泛型类型参数,我们可以使它更加通用:

private static int HowManySamplesInFirstPeriod
    IList samples,
    Func f // Let's generalize it a bit, since the function may return something other than int (some of the DateTime members return doubles, as I recall)

像往常一样,LINQ提供了更好的选择:

private static int HowManySamplesInFirstPeriod
    IList samples,
    Func f)
{
  var firstVal = f(samples.First().Date);
  return samples.Count(dt => f(dt.Date) = firstVal)
}

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有