C#隐式/显式转换为类型泛型类的泛型类型

时间:2018-02-21 09:13:33

标签: c# explicit generic-type-argument implicit-cast

我有一个类似下面的类来保存多个对象。

在瞬间,可以使用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'会起作用。当IHolderBusing 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

0 个答案:

没有答案