【发布时间】:2019-03-11 09:06:54
【问题描述】:
让下面的接口:
interface IFoo
{
void Foo();
}
interface IBar
{
void Bar();
}
interface IFooBar : IFoo, IBar
{
// No extra required feature.
}
还有班级:
class Booh : IFoo, IBar
{
public void Foo() { }
public void Bar() { }
}
我不能将Booh 用作IFooBar,尽管Booh 实现了IFooBar 所需的一切,因为它没有正式实现它。
为了允许在不将Booh 更改为class Booh : IFooBar 的情况下将Booh 用作IFooBar,我考虑过(基于另一个SO 问题)关于编写包装器:
class FooBar<T> : IFooBar where T : IFoo, IBar
{
public T Value { get; private set; }
public FooBar(T value)
{
Value = value;
}
public void Foo() { Value.Foo(); }
public void Bar() { Value.Bar(); }
}
问题是我可以照原样做!
例如,如果我使用这个包装类作为字典键,它将使用包装器的引用而不是被包装对象的引用。
如果我这样做:someDictionary.Add(new FooBar<Booh>(someBooh), whatever); 然后someDictionary.Remove<Booh>(new FooBar(someBooh)); 它不会删除我首先添加的Booh,因为我创建了两个不同的包装器,每个包装器都有自己的地址。
为了解决这个问题,我重写/实现了一些用于相等检查和哈希码的方法:
class FooBar<T> : IFooBar where T : IFoo, IBar
{
// Same as above...
public bool Equals(FooBar<T> other)
{
return Value.Equals(other.Value);
}
public override bool Equals(object obj)
{
var cast = obj as FooBar<T>;
if (null != obj && null == cast || obj == null)
{
return false;
}
return Value.Equals(cast.Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
}
这可能会导致字典使用包装的对象引用,我还没有测试过。
所以,我的问题是:我是否需要覆盖和/或实施其他方法以涵盖大多数(如果不是全部)用例?我希望该包装器的行为就像是被包装的对象,而不是另一个对象。谢谢!
编辑:也许我可以改为将其设为结构并依靠自动装箱将包装器结构包装到一个对象中,该对象将其哈希码和相等检查方法委托给该结构,从而使用被包装的对象引用?
【问题讨论】:
标签: c# dictionary interface hashcode strong-typing