【发布时间】:2014-03-21 22:30:53
【问题描述】:
我不确定如何更好地表达这个问题,但我在尝试多次创建通用接口字典时遇到了以下问题。这通常是在尝试创建处理不同类型的注册表类型集合时发生的:
namespace GenericCollectionTest
{
[TestFixture]
public class GenericCollectionTest
{
interface IValidator<T>
{
bool Validate(T item);
}
class TestObject
{
public int TestValue { get; set; }
}
private Dictionary<Type, IValidator<object>> Validators = new Dictionary<Type, IValidator<object>>();
class BobsValidator : IValidator<TestObject>
{
public bool Validate(TestObject item)
{
if (item.TestValue != 1)
{
return false;
}
}
}
[Test]
public void Test_That_Validator_Is_Working()
{
var Test = new TestObject {TestValue = 1};
Validators.Add(typeof(BobsValidator), new BobsValidator());
Assert.That(Validators[typeof(TestObject)].Validate(Test));
}
}
}
但是,编译失败,因为 BobsValidator 不能分配给参数类型 IValidator。基本上,我不需要验证器之外的类型安全,但是一旦我进入其中,我就不需要接口的使用者将其强制转换为他们想要使用的类型。
在 Java 中,我可以:
Dictionary<Type, IValidator<?>>
我知道我可以做这样的事情(ala IEnumerable):
interface IValidator
{
bool Validate(object item);
}
interface IValidator<T> : IValidator
{
bool Validate(T item);
}
abstract class ValidatorBase<T> : IValidator<T>
{
protected bool Validate(object item)
{
return Validate((T)item);
}
protected abstract bool Validate(T item);
}
然后让字典采用 IValidator 并扩展 ValidatorBase,但似乎必须有更好的方法,我没有看到。或者,这只是整体设计不佳?看来我需要这样的结构:
WhatTheHecktionary<T, IValidator<T>>
谢谢!
【问题讨论】:
-
您的抽象版本是一个很好的起点。从那里您只需要一个可以在运行时为您提供正确实现的工厂。问题是您可以向调用代码公开的只是 IValidator
标签: c# generics collections idictionary