在下面的代码我希望能够隐式地从投elements至baseElements因为TBase可以隐式转换IBase.
public interface IBase { }
public interface IDerived : IBase { }
public class VarianceBug
{
public void Foo<TBase>() where TBase : IBase
{
IEnumerable<TBase> elements = null;
IEnumerable<IDerived> derivedElements = null;
IEnumerable<IBase> baseElements;
// works fine
baseElements = derivedElements;
// error CS0266: Cannot implicitly convert type
// 'System.Collections.Generic.IEnumerable<TBase>' to
// 'System.Collections.Generic.IEnumerable<IBase>'.
// An explicit conversion exists (are you missing a cast?)
baseElements = elements;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到了评论中提到的错误.
引用规范:
A型
T<A1, …
我有这个简单的代码:
public interface IReader<out T>
{
IEnumerable<T> GetData();
}
Run Code Online (Sandbox Code Playgroud)
这个接口应该在T上协变,我用这种方式:
private static Func<bool> MakeSynchroFunc<T>(IReader<T> reader) where T : IComposite
{
return () => Synchronize(reader);
}
Run Code Online (Sandbox Code Playgroud)
注意T的约束来实现IComposite.同步方法接受IReader<IComposite>输入:
private static bool Synchronize(IReader<IComposite> reader)
{
// ......
}
Run Code Online (Sandbox Code Playgroud)
编译器告诉我它无法转换IReader<T>为IReader<IComposite>尽管T的约束和IReader的协方差.
我在这里做错了吗?编译器应该能够验证约束,协方差应该让我使用我IReader<T>的IReader<Icomposite>,不是吗?
谢谢.
所以我只是在使用我正在处理的状态机类型,并且大多想要尝试使用Activator.CreateInstance方法来查看它是什么样的,我遇到了一个问题,我似乎无法使用该where子句作为我想.如果我只是个白痴,我会提前道歉,大家都会把我从这里拉出来.所以我有2个小班.
public class TransitionContainer<TTransition, TStateTo> :
ITransitionContainer<TTransition, TStateTo>
where TTransition : ITransition
where TStateTo : IState
{
public TransitionContainer()
{
StateTo = typeof(TStateTo);
Transition = Activator.CreateInstance<TTransition>();
}
public Type StateTo { get; private set; }
public TTransition Transition { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
以及
public class StateContainer<T> : IStateContainer<T> where T : IState
{
private Dictionary<Type, TransitionContainer<ITransition, IState>> _transitions =
new Dictionary<Type, TransitionContainer<ITransition, IState>>();
public StateContainer()
{
State = Activator.CreateInstance<T>();
}
public T State { get; private …Run Code Online (Sandbox Code Playgroud) public void Foo<T>(Func<T> bar)
where T: IMyInterface
{
Func<IMyInterface> func = bar;
}
Run Code Online (Sandbox Code Playgroud)
自从我理解了协方差以来已经有一段时间了,但这不应该编译吗?
任何bar可以返回的东西也是IMyInterface.什么似乎是问题?