我有一个类似下面的类来保存多个对象。
在瞬间,可以使用MultiHolder<...>
获取对象。
我希望能够通过转换MultiHolder<IHolderA, IHolderB, IHolderC> multiHolder = new MultiHolder<IHolderA, IHolderB, IHolderC>(new HolderA(), new HolderB(), new HolderC());
//Works
IHolderA HolderA_byGet = multiHolder.Get<IHolderA>();
//Works??!
IHolderB HolderB_byExplicitCast = (HolderB)multiHolder;
//Throws InvalidCastException
IHolderB HolderB_byEcplicitInterfaceCast = (IHolderB)multiHolder;
//Will not compile
//HolderC HolderC_byImplicitCast = multiHolder;
//Will not compile
//IHolderC HolderC_byImplicitInterfaceCast = multiHolder;
IHolderB
我首先尝试将其投放到InvalidCastException
。导致Tholder2
。为什么不使用隐式演员?
测试时我发现将它投射到'HolderB'会起作用。当IHolderB
为using System;
using System.Collections.Generic;
namespace MultiHolderExample
{
public interface IHolder{}
public abstract class MultiHolder : IHolder
{
private readonly Dictionary<Type, IHolder> _holders;
protected MultiHolder(Type[] types, IHolder[] holders)
{
_holders = new Dictionary<Type, IHolder>();
for (int i = 0; i < types.Length; i++)
{
if (!types[i].IsInstanceOfType(holders[i]))
throw new ArgumentException($"Can't convert \"{holders[i].GetType().Name}\" to \"{types[i].Name}\"");
_holders.Add(types[i], holders[i]);
}
}
public T Get<T>() where T : IHolder
{
if (_holders.TryGetValue(typeof(T), out IHolder holder))
return (T)holder;
throw new ArgumentException("Unknown Type of holder " + typeof(T).Name);
}
}
#region Generic holders
public class MultiHolder<Tholder1, Tholder2> : MultiHolder
where Tholder1 : IHolder
where Tholder2 : IHolder
{
#region Constructor
public MultiHolder(Tholder1 f1, Tholder2 f2) :
base(new[] { typeof(Tholder1), typeof(Tholder2) }, new IHolder[] { f1, f2 })
{ }
public static implicit operator Tholder1(MultiHolder<Tholder1, Tholder2> holder) => holder.Get<Tholder1>();
public static implicit operator Tholder2(MultiHolder<Tholder1, Tholder2> holder) => holder.Get<Tholder2>();
#endregion
}
public class MultiHolder<Tholder1, Tholder2, Tholder3> : MultiHolder
where Tholder1 : IHolder
where Tholder2 : IHolder
where Tholder3 : IHolder
{
#region Constructor
public MultiHolder(Tholder1 f1, Tholder2 f2, Tholder3 f3) :
base(new[] { typeof(Tholder1), typeof(Tholder2), typeof(Tholder3) }, new IHolder[] { f1, f2, f3 })
{ }
public MultiHolder(MultiHolder<Tholder1, Tholder2> mf1, Tholder3 f3) :
base(new[] { typeof(Tholder1), typeof(Tholder2), typeof(Tholder3) }, new IHolder[] { mf1.Get<Tholder1>(), mf1.Get<Tholder2>(), f3 })
{ }
public static implicit operator Tholder1(MultiHolder<Tholder1, Tholder2, Tholder3> holder) => holder.Get<Tholder1>();
public static implicit operator Tholder2(MultiHolder<Tholder1, Tholder2, Tholder3> holder) => holder.Get<Tholder2>();
public static implicit operator Tholder3(MultiHolder<Tholder1, Tholder2, Tholder3> holder) => holder.Get<Tholder3>();
#endregion
}
#endregion
public interface IHolderA : IHolder { }
public class HolderA : IHolderA { public int HolderAVal; }
public interface IHolderB : IHolder { }
public class HolderB : IHolderB { public int HolderBVal; }
public interface IHolderC : IHolder { }
public class HolderC : IHolderC { public int HolderCVal; }
}
时,为什么会这样做。
另外,为什么我不能使用隐式cassts,即使它们被定义为?
以下代码,为完整示例:
-t duration