Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 匿名函数与非匿名函数一样强大_C#_Generics - Fatal编程技术网

C# 匿名函数与非匿名函数一样强大

C# 匿名函数与非匿名函数一样强大,c#,generics,C#,Generics,我一直认为匿名函数和命名函数一样强大,直到我想把一个私有命名函数变成一个匿名函数,因为只有一个方法体需要调用这个函数。一个简单的例子: public void Init(List<int> numbers, List<string> texts) { int n = GetFirst(numbers); string t = GetFirst(texts); } private T GetFirst<T>(List<T> list) {

我一直认为匿名函数和命名函数一样强大,直到我想把一个私有命名函数变成一个匿名函数,因为只有一个方法体需要调用这个函数。一个简单的例子:

public void Init(List<int> numbers, List<string> texts)
{
  int n = GetFirst(numbers);
  string t = GetFirst(texts);
}

private T GetFirst<T>(List<T> list)
{
  return list[0];
}
但是我只能用定义的泛型参数来实例化它

GetFirstDelegate<string> getFirst = list => list[0];
GetFirstDelegate getFirst=list=>list[0];
但与占位符通用参数不同:

GetFirstDelegate<T> getFirst = list => list[0];
GetFirstDelegate getFirst=list=>list[0];
这让我觉得匿名方法不如命名方法强大——至少在泛型用法方面是如此——或者我遗漏了什么吗?

看看这个问题,你可以看到泛型匿名函数在C#中是不可能的。当编译器必须使用常规泛型方法时进行映像。它实际上为它所调用的每种类型生成一个重载(至少简单地说)。当您使用泛型参数声明变量时,编译器在这个实例中应该如何做?它无法生成具有不同泛型参数的新变量


希望这是清楚的。您基本上只需要知道泛型方法和类是编译时的事情

您实际要做的是创建一个类似的通用变量

Func<List<T>, T> getFirst<T> = list => list[0];
Func getFirst=list=>list[0];

但不幸的是,这是无效的,因为变量不能是泛型的。只有类型(接口、类、结构)、委托和方法可以是泛型的。

接受
List
作为输入并返回
T
的函数的签名是
Func
,而不是
Func

我想这就是你想要的:

private Func<List<T>, T> GenGetFirst<T>()
{
    return list => list[0];
}
private Func GenGetFirst()
{
返回列表=>list[0];
}
用法:

public void Init(List<int> numbers, List<string> texts)
{
    int n = GenGetFirst<int>()(numbers);
    string t = GenGetFirst<string>()(texts); 
}
public void Init(列表编号、列表文本)
{
int n=GenGetFirst()(数字);
字符串t=GenGetFirst()(文本);
}
或者以更清晰的方式:

public void Init(List<int> numbers, List<string> texts)
{
    Func<List<int>, int> intFunc = GenGetFirst<int>();
    Func<List<string>, string> stringFunc = GenGetFirst<string>();

    int n = intFunc(numbers);
    string t = stringFunc(texts);
}
public void Init(列表编号、列表文本)
{
Func intFunc=GenGetFirst();
Func stringFunc=GenGetFirst();
int n=int func(数字);
字符串t=stringFunc(文本);
}

当然,以你的例子来说,LINQ已经为
IEnumerable
定义了一个
.First()
,我很感激你的回答,但我想摆脱命名方法,用一个匿名函数来表达它,这在C语言中是不可能的,就像我刚刚学到的那样。
public void Init(List<int> numbers, List<string> texts)
{
    int n = GenGetFirst<int>()(numbers);
    string t = GenGetFirst<string>()(texts); 
}
public void Init(List<int> numbers, List<string> texts)
{
    Func<List<int>, int> intFunc = GenGetFirst<int>();
    Func<List<string>, string> stringFunc = GenGetFirst<string>();

    int n = intFunc(numbers);
    string t = stringFunc(texts);
}