所以我已经使用了一段时间了,我在弄乱语法时偶然发现了它。但我仍然不知道为什么它有效,有人可以向我解释一下吗?怎么会被打破?
public T LoadData(Func<Z, T> func, Z arg) where T: class
{
T data = func(arg);
return data;
}
public T LoadData(Func<Z, T> func) where T: class
{
return LoadData<object, T>(arg => func(), null); // <--- Why does the arg => func() part work? It basically ignores the parameter when it gets passed in for some reason...
}
我这样使用它:
public IEnumerable<CategoryTypes> GetCategories()
{
return LoadData(CategoryProvider.GetCategoriesByGroupId, 12);
}
OR
public IEnumerable<Person> GetStatesLookup()
{
return LoadData(StatesProvider.GetStates);
}
PS:这是伪代码,我使用它的真正原因比上面的例子更复杂......
更新以修复我在此处输入此内容时意外逆转泛型的问题... 更新2:修复意外定义arg a T而不是Z
答案 0 :(得分:2)
这是因为您正在创建一个满足Func<T,Z>
答案 1 :(得分:2)
它将Func<T, Z>
包裹在另一个Func<T, Z>
中。新Func<T, Z>
所做的唯一事情是考虑Func<T, Z>
来调用旧的arg
没有。
您可以使用arg => func()
或func
arg => func(arg)
答案 2 :(得分:2)
方法LoadData
是T
的通用方法,其中T
必须是class
。但是,T
作为传递给它的Func
的单个参数类型进一步传入。最后,Z
用作Func
的通用返回类型。
简而言之,传入的Func
必须与调用LoadData
时定义的类型相同。然后它返回一个不同的类型,当然,当您将Func
发送到LoadData
时,会定义该类型。
所以,这就是为什么这样做的原因:
LoadData(CategoryProvider.GetCategoriesByGroupId, 12);
此情况下的T
为int
,您传入的Func
会收到int
类型的单个参数。它返回的是什么,我不知道,但没关系 - 它被用作Z
。
这个电话可能静态地看起来像这样:
public int LoadData(Func<int, void> func, int arg)
要解决第二组伪代码 - 我不相信即使编译也不相信你有一个真实的具体例子就是这样。您不满意T
,而void
在那里无效。这是为什么伪代码不适合这里的问题的完美例子。
答案 3 :(得分:0)
似乎是“翻译”一个不带参数的函数到一个函数中。第二个重载中的null
可以是任何值,因为它只传递给忽略其参数的函数。
但是,显示的代码没有意义。在第一次重载中,您有:
T data = func(arg);
然而func
的返回类型是Z
,而不是T
。因此,仅当Z
为T
时才会有效。
然后在第二次重载中,调用func
时没有参数,但它仍然是Func<T,Z>
,这意味着它必须采用单个T
参数。
如果交换了类型参数(Z
作为参数类型而T
作为返回类型),则更有意义,第二个重载不使用Z
:
public T LoadData(Func<Z,T> func, Z arg) where T: class
{
T data = func(arg);
return data;
}
public T LoadData(Func<T> func) where T: class
{
return LoadData<object, T>(arg => func(), null);
}