【问题标题】:having trouble using delegates in c#在 C# 中使用委托时遇到问题
【发布时间】:2015-10-21 03:00:39
【问题描述】:

通过使用委托,我希望使用以下代码将 IEnumerable 项目中的数字 5 打印到屏幕上;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using extended;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<int> cities = new[] { 1, 2, 3, 4, 5 };
            IEnumerable<int> query = cities.StartsWith(hello);

            foreach (var item in query)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
        static int hello(int x)
        {
        return x > 4 ? x : 0;
        }
    }
}
namespace extended
{
    public static class A
    {
        public static IEnumerable<T> StartsWith<T>(this IEnumerable<T> input, inputdelegate<T> predicate)
        {
            foreach (var item in input)
            {
                if (item.Equals(predicate))
                {
                    yield return item;
                }
            }
        }
        public delegate int inputdelegate<T>(T input);
    }
}

代码编译没有任何错误,但没有在屏幕上显示输出。知道我哪里可能出错了吗?

【问题讨论】:

  • if (item.Equals(predicate)) 始终为假。你的意图是什么?
  • @AlexD 在 {1,2,3,4,5} 谓词 = 5 和 foreach (var item in input) 中的数字 5 上,当循环迭代到项目 5 时,(item.Equals(predicate)) 应该返回 true?
  • @RehanKhan 我在下面的答案中为您的源代码提供了一些修复,这些修复会产生您正在寻找的内容。祝你好运!
  • 我猜谓词应该是bool,返回true的值是5,然后被调用为if(predicate(item)){yield return item;}

标签: c# asp.net delegates


【解决方案1】:

你没有调用你的谓词。此外,inputdelegate 的返回类型可能应该是 T。将您的代码更改为:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using extended;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<int> cities = new[] { 1, 2, 3, 4, 5 };
            IEnumerable<int> query = cities.StartsWith(hello);

            foreach (var item in query)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
        static int hello(int x)
        {
        return x > 4 ? x : 0;
        }
    }
}
namespace extended
{
    public static class A
    {
        public static IEnumerable<T> StartsWith<T>(this IEnumerable<T> input, inputdelegate<T> predicate)
        {
            foreach (var item in input)
            {
                if (item.Equals(predicate(item)))
                {
                    yield return item;
                }
            }
        }
        public delegate T inputdelegate<T>(T input);
    }
}

更新:基于 AlexD 的 cmets,您应该考虑将测试更改为:

if (predicate(item))

并将您的委托更新为:

public delegate bool inputdelegate<T>(T input);

并将您的 Hello 函数更新为:

static bool hello(int x)
{
    return x > 4;
}

【讨论】:

  • "inputdelegate 应该有一个返回类型 T" 如果它是一个谓词,它不应该返回bool吗?
  • @Tyree Jackson 正确。错过了传递谓词的参数:) 非常感谢。
  • 作者并没有真正使用 LINQ 术语意义上的谓词。他创建了一个自定义委托来编写函数,将与参数相同类型的值返回给委托。我同意,布尔返回会更好,但最终,这取决于作者。
  • 我对编程知之甚少,但到目前为止我对委托返回类型的理解是它确实取决于您的要求。代表可以根据您的需要返回任何类型。这跑题了,回到主题:当我没有将参数传递给谓词委托时,为什么它没有在编译或运行时抛出任何错误?
  • @RehanKhan 您没有收到编译时错误,因为 .Equals 接受 System.Object 类型的参数。所有委托都派生自 System.Object,因此委托本身是返回 false 的有效测试。实际上,您正在比较 ((object) 1) == ((object) delegate(hello)) 这是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多