我有一组方法,每个方法都返回各种类型 T 的 ObservableCollection,并且希望能够编写一个基于发送的枚举值返回这些方法的工厂方法。例如,假设我有以下高度现实的方法...
public ObservableCollection<Gribble> GetGribbles() {
return new ObservableCollection<Gribble>();
}
public ObservableCollection<Gribulator> GenerateGribulators() {
return new ObservableCollection<Gribulator>();
}
public ObservableCollection<Knepple> MakeKnepples() {
return new ObservableCollection<Knepple>();
}
...以及以下枚举...
public enum ListNames {
Gribbles,
Gribulators,
Knepple
}
那么我希望能够做到这一点...
Func<ObservableCollection<Gribble>> someGribbles =
MakeFunc<Gribble>(ListNames.Gribbles);
原因是我有一个带有这样签名的帮助器类...
public void GetList<T>(ListNames listName,
Func<ObservableCollection<T>> serviceCall,
Action<ObservableCollection<T>> handleList)
serviceCall是获取列表的方法,handleList是回调方法。目前,无论何时调用此方法,代码都必须传递获取列表的实际函数。
然而,这被证明是一个糟糕的设计选择,因为这意味着如果代码的两部分都为特定列表调用 GetList,它们可能会传入两个不同的服务调用,这将导致结果不一致。我想将服务调用封装在 MakeFunc 方法中,该方法将从 GetList 调用,这意味着使用 GetList 的代码永远不会看到实际的服务调用,因此不会做任何错误。
我已经尝试了一些东西,但正在努力获得任何可以编译的东西。我得到的最接近的是以下...
public Func<ObservableCollection<T>> MakeFunc<T>(ListNames listName) {
switch (listName) {
case ListNames.Gribbles:
return GetGribbles;
case ListNames.Gribulators:
return GenerateGribulators;
case ListNames.Knepple:
return MakeKnepples;
default:
throw new ArgumentException("Unknown list name");
}
}
...但这会导致编译器错误,类似于“GetGribbles() 有错误的返回类型”,以及当我将鼠标悬停在 MakeFunc 方法中的 GetGribbles 上时弹出的工具提示说
Expected a method with
'ObservableCollection<T> GetGribbles()'
signature
可以做我想做的事吗?如果是这样,有人能解释我做错了什么吗?
如果有什么不同的话,我在 Visual Studio 2010 中使用 C# 4.0。
最佳答案
如果 Gribble
、Gribulator
和 Knepple
类共享公共(public)基类型或实现公共(public)接口(interface),那么您可以这样做:
public Func<ObservableCollection<ICommonInterface>> MakeFunc(ListNames listName)
{
...
}
如果它们没有共同的基本类型或接口(interface),您必须这样做:
public Func<ICollection> MakeFunc(ListNames listName)
{
...
}
诚然,这不是一个很好的解决方案。注意:您可以将 ICollection
替换为 INotifyCollectionChanged
或您最需要的任何非通用接口(interface)。
在这两种情况下,您都必须依赖调用者来指定数据类型(即使调用者也指定了枚举值)。因此,您也可以摆脱枚举,并进行如下操作:
public Func<ObservableCollection<T>> MakeFunc<T>()
{
if (typeof(T) == typeof(Gribble))
return () => GetGribbles() as ObservableCollection<T>;
if (typeof(T) == typeof(Gribulator))
return () => GenerateGribulators() as ObservableCollection<T>;
if (typeof(T) == typeof(Knepple))
return () => MakeKnepples() as ObservableCollection<T>;
throw new ArgumentException("Unknown list name");
}
然后调用者可以简单地写:
var gribblesFunc = MakeFunc<Gribble>();
关于c# - 如何编写 C# 方法来返回基于枚举参数的 Func<T> ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17225595/