下面是一些没有编译的C#代码,给出了以下消息:
不能从“out”转换为“out Component”
public void Get<T>(out T c) where T : Component
{
m_components.TryGetValue(typeof(T), out c);
}下面是编译的代码:
public void Get<T>(out T c) where T : Component
{
Component temp;
m_components.TryGetValue(typeof(T), out temp);
c = (T)temp;
}我想知道为什么第一段代码无效,因为“其中T: Component"明确声明T是类型组件。
谢谢
发布于 2009-12-03 07:10:33
我要尝试一下@Rex的答案的更详细的版本,以及@Courtney签名的稍微修正的版本,因为类型是组件,而不是对象。考特尼的回答基本上是对的,只是类型有点离谱。
bool TryGetValue(Type key, out Component result)
{
if (this.Contains(key))
{
result = this[key]; // the type of result is Component!
return true;
}
return false;
}通过将T作为对象类型传递,您将尝试将基本类型组件隐式转换为子类型T。这就是第二个示例工作的原因。TryGetValue不知道您的泛型类型T,它认为m_Components中的所有东西都是一个组件对象。
这是一件很常见的事情,你会被困在后面思考。因为它是一个参数,而不是返回类型,所以您会认为它应该像任何其他参数一样工作。但是,由于它是一个out,因此实际上更好地将其视为用于此目的的返回类型。它将尝试将其内部工作的值分配给您提供的参数。
发布于 2009-12-03 06:53:55
这是因为out参数类型不能是协变/反变。变量的类型必须与参数类型完全匹配。
请参见:
class Super { }
class Sub : Super { }
void Test(out Super s)
{
s = new Super();
}
void Main()
{
Sub mySub = new Sub();
Test(out mySub); //doesn't work
}发布于 2009-12-03 06:43:43
我认为问题在out中,它与泛型无关。
我们可以产生如下相同的错误
class A
{
}
void fn(out object x)
{
x= new object();
}
void main()
{
A x;
fn(out x); //error
}https://stackoverflow.com/questions/1838072
复制相似问题