Skip to main content
 首页 » 编程设计

c#之将不同类型的通用对象保存在一个集合中

2024年02月20日33birdshome

我一直在为一个项目构建一个小型访问规则模块,其中每个特定规则都由通用 Rule<TEntity> 反射(reflect)目的。该规则采用委托(delegate)来执行特定逻辑。

有一个RulesContext提供方法来检查对特定实体“foo”的访问的类,如下所示:

rulesContext.CanIRead<Foo>(myFoo); 

我的意图是将设置过程中构建的所有规则存储到一个集合中。但我尝试过的每一种方法都会走向死胡同。

我想到了这样的事情:

IDictionary<Type, Rule<object>> _rules = new Dictionary<Type, Rule<object>>(); 

和:

var fooRule = new Rule<Foo>(foo => foo.FullfillsACertainFooCriterion()) 
_rules.Add(typeof(Foo), fooRule); 

CanIRead实现将确保正确使用字典:

public bool CanIRead<TEntity>(TEntity entity) 
{ 
    var rule = _rules[typeof(entity)]; 
    return rule.CanIRead(entity); 
} 

但编译器不喜欢这样:Rule<Foo>不能分配给 Rule<object> 类型的参数.哪一种有意义,因为它会破坏契约(它说我可以使用字典的方法和任何对象作为参数,这对于只接受 Foo 类型对象的 fooRule 不成立。- Liskov 原则)

但是我想不出解决这个问题的方法。我如何存储 Rule一个集合中具有不同类型的对象?

请您参考如下方法:

你能做到吗:

[TestFixture] 
public class ContraVariance 
{ 
    [Test] 
    public void TestNameTest() 
    { 
        var rules = new List<IRule<object>>(); //object is used just for demo here, probably some interface of yours is better 
        rules.Add(new Rule<A>()); 
        rules.Add(new Rule<B>()); 
    } 
} 
public class A { } 
public class B { } 
 
public class Rule<TEntity> : IRule<TEntity> 
{ 
 
} 
 
public interface IRule<out T> 
{ 
} 

如果不是,我认为你必须有一个非通用的 IRule 或 RuleBase(类) out 关键字 int 接口(interface)意味着 T 仅输出(协变)你可以阅读它 here . 我想这对你的情况来说是个问题,我怀疑这些规则有将 TEntity 作为参数传递的方法。