0

所以我一直在使用它一段时间,我在弄乱它的时候偶然发现了语法。但是我仍然不知道它为什么起作用,有人可以向我解释一下吗?这是如何分解的?

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);
}

或者

public IEnumerable<Person> GetStatesLookup()
{
  return LoadData(StatesProvider.GetStates);
}

PS:这是伪代码,我使用它的真正原因比上面的例子要复杂一些......

更新以修复我在此处键入时意外反转泛型...更新 2:修复了意外定义 arg a T 而不是 Z

4

4 回答 4

2

这是因为您正在创建一个满足Func<T,Z>

于 2013-09-19T14:26:32.350 回答
2

它包裹Func<T, Z>在另一个中Func<T, Z>。新的唯一要做的就是考虑Func<T, Z>就叫旧的。Func<T, Z> arg

arg => func()你可以简单地换掉func,或者arg => func(arg)

于 2013-09-19T14:27:21.767 回答
2

该方法LoadData是通用的,T其中T必须是 a class。但是,进一步作为传递给它T的单个参数类型传入。Func最后,Z用作Func.

所以简而言之,Func传入的 必须接收与调用时定义的类型相同的类型LoadData。然后它返回一个不同的类型,这当然是在你发送Functo时定义的LoadData

所以,这就是为什么它有效:

LoadData(CategoryProvider.GetCategoriesByGroupId, 12);

T这种情况下是int,并且Func您传入的 接收一个类型为 的参数int。它返回什么,我不知道,但没关系 - 它被用作Z.

该调用可能静态看起来像这样:

public int LoadData(Func<int, void> func, int arg)

为了解决第二组伪代码 - 我不相信它甚至可以编译,也不相信你有一个像这样的真实具体示例。你不满足T并且void不会在那里有效。这是一个完美的例子,说明为什么伪代码不是这里问题的好候选者。

于 2013-09-19T14:27:39.570 回答
0

它似乎正在将一个不带参数的函数“翻译”成一个带参数的函数。第二null个重载中的 可以是任何值,因为它只传递给参数被忽略的函数。

但是,显示的代码没有意义。在第一次重载中,您有:

T data = func(arg);

然而,返回类型funcZ,不是T。所以这只有ZT.

然后在第二个重载中,func不带参数调用,但它仍然是 a 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);
}
于 2013-09-19T14:44:45.510 回答