c# - 是否可以将此类变成通用类?

标签 c# generics delegates

是否有人能够“泛化”这个问题底部列出的类?我希望该类不要锁定到“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/

相关文章:

c# - 犀牛模拟 : How to verify that a constructor was called

java 泛型 : runtime type-checking to determine a strategy

c# - 参数类型对象不可分配给 System.Func<object> 错误

c# - 林克 : select value in a datatable column

c# - 如何手动将带有列表的 View 模型映射到 dto

java - 如何将通配符泛型与 Sets.powerSet 一起使用

ios - Swift,如何告诉 Controller 另一个 Controller 是它的委托(delegate)

c# - 有人可以解释这种通用语法吗?

c# - 在 C# 中分词器/拆分?

angular - 为什么 Typescript 无法推断 RxJs 流中的元组返回类型?