有人能够“通用化”此问题底部列出的课程吗?我希望该类不要被锁定为“ GetStateDelegate”类型的委托,而应被锁定为一般委托。那可能吗?

我尝试了几件事,但是1)C#不喜欢这种类型的类声明:

public class StringToMethodMapper<T> where T: System.Delegate


这将产生“不能使用System.Delegate作为类型参数约束”

提示使我走上正轨的提示表示赞赏。另外,如果存在解决方案,我希望消费者受更改的影响尽可能小。例如,我不想更改“ Add(字符串,委托)”的调用代码。

代码:

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的库,该库对具有委托约束的泛型使用IL重写-您可以在代码中使用相同的IL重写器。不过这很丑。基本上,IL支持所需的约束,但C#不支持。请注意,“它应该是从MulticastDelegate派生但不包括MulticastDelegate本身的类型”没有任何可能的限制,因此有人可以创建StringToMethodMapper<MulticastDelegate>,但这很不方便。

如果您乐于坚持一种委托人签名(例如,“始终有三个参数且返回无效”),则可以使用George回答中的方法。如果它适用于任何委托类型,那么您将陷入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/

10-11 23:15
查看更多