gpt4 book ai didi

C# 不是可分配类型 - 泛型

转载 作者:太空狗 更新时间:2023-10-29 21:32:38 24 4
gpt4 key购买 nike

所以我只是在研究我正在研究的状态机类型,主要是想尝试一下 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; }
}

还有

  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 set; }

public int TransitionCount
{
get { return _transitions.Count; }
}


public void AddTransition<TTransition, TStateTo>() where TTransition : ITransition, new()
where TStateTo : IState, new()
{
var transitionContainer= new TransitionContainer<TTransition, TStateTo>();

_transitions.Add(typeof(TTransition), transitionContainer);
}

于是上线_transitions.Add(typeof(TTransition), transitionContainer);我收到 cannot convert TransitionContainer<TTransition,TStateTo> expression to type TransitionContainer<ITransition,IState>错误。

如果我将通用参数更改为

var transitionContainer= new TransitionContainer<ITransition, IState>();

它工作正常,但我想使用 new() 的继承类型,所以我可以确定我可以实例化它们。

如果我做错了什么,我再次道歉,我只是碰壁了,我的谷歌搜索没有把我引向正确的方向。我没有包含任何其他接口(interface)或类,因为它们似乎不是问题的一部分,但如果需要,我可以附加它们。感谢您的帮助!

最佳答案

出现这个问题是因为:

  1. ITransitionContainer不是 covariant interface在其类型参数上。
  2. AddTransition方法通用参数是 not constrainedreference types .
  3. _transitions不是 ITransitionContainer 的字典值,因此无需将其更改为 Dictionary<Type, ITransitionContainer<ITransition, IState>>我们仍然无法添加甚至适当限制的协变转换。

简化示例

考虑以下简化情况:

public interface ITransition
{

}

public class SomeTransition : ITransition
{

}

public interface ITest<TTransition>
where TTransition : ITransition
{
TTransition Value { get; }
}


public class SomeTest<TTransition> : ITest<TTransition>
where TTransition : ITransition
{
public TTransition Value
{
get
{
throw new NotImplementedException();
}
}
}

两者都会失败

public static void Do<TTransition>()
where TTransition : ITransition
{
ITest<ITransition> item = new SomeTest<TTransition>();
}

ITest<ITransition> item = new SomeTest<SomeTransition>();

如果你制作ITest协变

public interface ITest<out TTransition>

,那么它只会在泛型方法中失败。因为这里TTransition可以是结构和 co/(contra)variance doesn't work with value types :

public static void Do<TTransition>()
where TTransition : ITransition
{
ITest<ITransition> item = new SomeTest<TTransition>();
}

但是如果你使那个方法constrained to only reference types , 那么它在这两种情况下都有效:

public static void Do<TTransition>()
where TTransition : class, ITransition
{
ITest<ITransition> item = new SomeTest<TTransition>();
}

将相同的原则(outclass)应用于您的两个通用参数,它将完成工作。


针对您的特定案例的完整解决方案:

public interface IState
{ }

public interface ITransition
{ }

// !!!!! - Here we add out specifier
public interface ITransitionContainer<out TTransition, out TStateTo>
where TTransition : ITransition
where TStateTo : IState
{
Type StateTo
{
get;
}

TTransition Transition
{
get;
}
}

public interface IStateContainer<T> where T : IState
{
T State
{
get;
}
}


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; }
}


public class StateContainer<T> : IStateContainer<T> where T : IState
{
private Dictionary<Type, ITransitionContainer<ITransition, IState>> _transitions =
new Dictionary<Type, ITransitionContainer<ITransition, IState>>();

public StateContainer()
{
State = Activator.CreateInstance<T>();
}

public T State { get; private set; }

public int TransitionCount
{
get { return _transitions.Count; }
}

public void AddTransition<TTransition, TStateTo>()
// !!!!!! - Here we add class constraints
where TTransition : class, ITransition, new()
where TStateTo : class, IState, new()
{
var transitionContainer = new TransitionContainer<TTransition, TStateTo>();

_transitions.Add(typeof(TTransition), transitionContainer);
}
}

关于C# 不是可分配类型 - 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38035427/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com