是否有人能够“泛化”这个问题底部列出的类?我希望该类不要锁定到“GetStateDelegate”类型的委托(delegate),而是锁定到一般委托(delegate)。那可能吗?
我已经尝试了几件事,但是 1) C# 不喜欢这种类声明:
public class StringToMethodMapper<T> where T: System.Delegate
这会产生“不能使用 System.Delegate 作为类型参数约束”
让我走上正轨的提示非常感谢。此外,如果存在解决方案,我希望消费者尽可能少地受到更改的影响。例如,我不想更改“Add(string, delegate)”的调用代码。
代码:
public delegate bool GetStateDelegate(object someObject);
public class StringToMethodMapper
{
private Dictionary<string, GetStateDelegate> _methods;
public StringToMethodMapper()
{
_methods = new Dictionary<string, GetStateDelegate>();
}
public void Add(string key, GetStateDelegate method)
{
_methods.Add(key, method);
}
internal virtual GetStateDelegate GetMethodFor(string key)
{
foreach (var storedKey in _methods.Keys)
{
if (key.ToUpper().StartsWith(storedKey.ToUpper()))
{
return _methods[storedKey];
}
}
return null;
}
}
最佳答案
在使其通用化方面……好吧,这是有可能的。我有一个名为 Unconstrained Melody 的图书馆它对具有委托(delegate)约束的泛型使用 IL 重写 - 您可以在代码中使用相同的 IL 重写器。虽然它很丑陋。基本上 IL 支持您想要的约束,但 C# 不支持。请注意,“它应该是从 MulticastDelegate
派生的类型,但不包括 MulticastDelegate
本身”没有可能的约束......所以有人可以创建一个 StringToMethodMapper<MulticastDelegate>
但这很不方便。
如果您乐于坚持一种委托(delegate)签名(例如“总是三个参数和一个无效返回”),那么您可以使用 George 的回答中的方法。如果它应该用于任何 委托(delegate)类型,那么您将坚持使用 IL 重写方法或放弃约束。
(根据评论编辑。)
就代码的其余部分而言,这是对字典的非常缓慢的使用。目前你有 O(n) 查找。只需使用正常 Dictionary
通过 TryGetValue
访问, 但通过 StringComparer.OrdinalIgnoreCase
(或类似的东西)进入构造函数以获得不区分大小写的匹配。诚然,这不会得到一个开始匹配......但是你目前的方法无论如何都不是确定性的,因为你最终可以将“foo”和“fo”作为字典中的键,两者都会匹配 -所以你依赖于迭代器返回键的顺序。这不是个好主意。
如果你真的需要 StartsWith
行为,您可能想调查实现 trie - 或者如果您对 O(N) 查找感到满意,我会保留 List<KeyValuePair<string, TDelegate>>
明确表示您并没有真正将其用作字典。
关于c# - 是否可以将此类变成通用类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7240841/