我正在努力更好地理解函数式编程。提供了以下示例,此示例创建谓词lambda。然后创建一个静态方法来计算传递谓词条件的项目数。
public Predicate<string> longWords = (x) => x.Length > 10;
public static int Count<T>(T[] array, Predicate<T> predicate, int counter)
{
for (int i = 0; i < array.Length; i++)
{
if (predicate(array[i]))
{
counter++;
}
}
return counter;
}
我想让这个解决方案遵循Referential Transparency
原则,该原则规定您只能通过查看其参数的值来确定应用该函数的结果。
不幸的是longWords
并没有告诉我长字究竟意味着什么,我需要传递一个参数给longWords
告诉它长度使一个函数成长字,即不硬编码&#39; 10&#39;。
Predicates
只接受一个参数,并且longWords
需要Predicate<Tuple<string,int>>
,这就是它的挑战。
以下是我尝试解决方案,以及产生的两条错误消息。
public class BaseFunctions
{
public Predicate<Tuple<string, int>> longWords = (x) => x.Item1.Length > x.Item2;
public static int Count<T>(T[] array, Predicate<T> predicate, int counter)
{
for (int i = 0; i < array.Length; i++)
{
/// error below: Cannot convert from 'T' to 'string'
/// in the example provided predicate(array[i]) worked fine when the predicate had only string type
if (predicate(new Tuple<string, int>(array[i], 10)))
{
counter++;
}
}
return counter;
}
}
及其用法
BaseFunctions b = new BaseFunctions();
string[] text = ["This is a really long string", "Not 10"];
/// also error below on BaseFunctions.Count 'The type arguments for method BaseFunctions.Count<T>(T[], Predicate<T>, int) cannot be inferred from the usage. Try specifying the arguments explicitly
Console.WriteLine(BaseFunctions.Count(text, b.longWords, 0).ToString());
Console.ReadLine();
答案 0 :(得分:2)
我做:
public Func<string, int, bool> longWords = (str, number) => str.Length > number;
而不是:
public Predicate<Tuple<string, int>> longWords = (x) => x.Item1.Length > x.Item2;
这只是因为我认为使用string
和int
然后返回bool
而不是带谓词的函数更容易处理string
和int
的元组,并返回bool
。加上这个版本的元组类型很麻烦。如果您正在使用C#7
及更高版本,请考虑新的元组类型。
然后从:
更改方法签名public static int Count<T>(T[] array, Predicate<T> predicate, int counter)
为:
public static int Count<T>(T[] array, Func<T, int, bool> predicate, int counter)
为了适应上述代表类型的变化。
然后需要更改if
条件:
if (predicate(new Tuple<string, int>(array[i], 10)))
为:
if (predicate(array[i], 10))
为了适应上述代表类型的变化。
另请注意,在C#
中,您需要像这样定义数组:
string[] text = { "This is a really long string", "Not 10" };
而不是[
]
大括号。
现在您的使用代码变为:
BaseFunctions b = new BaseFunctions();
string[] text = { "This is a really long string", "Not 10" };
Console.WriteLine(BaseFunctions.Count(text, b.longWords, 0).ToString());
Console.ReadLine();