类型受限的C#类型无效转换 [英] Invalid Cast of Type Constrained C# Generic
问题描述
$ b
public class ConfigurationElementCollection< TElement,TParent>
是一个
where TElement:ParentedConfigElement< TParent> ;, new()
其中TParent:class
{
public TParent ParentElement {get;组; }
protected ConfigurationElement CreateNewElement()
{
// ************************* *************************
//编译器为此行提供了类型转换错误!
// ******************************************** ******
返回新的TElement {ParentCollection = this};
}
}
公共类ParementedConfigElement< TParent> :ConfigurationElement其中TParent:class
{
internal ConfigurationElementCollection< ParentedConfigElement< TParent>,TParent>
ParentCollection {get;组; }
保护TParent父母
{
获得
{
返回ParentCollection!= null? ParentCollection.ParentElement:null;
code
$ b上面的代码注释表示,编译器会给出一个错误:
不能隐式地将类型'Shared.Configuration.ConfigurationElementCollection< TElement,TParent>'转换为'Shared.Configuration。 ConfigurationElementCollection< Shared.Configuration.ParentedConfigElement< TParent>,TParent>
我不希望这个错误,因为编译器也知道<由于我指定的泛型类型约束,code> TElement
Shared.Configuration.ParentedConfigElement< TParent>
。
不过,我想我会明确地指出这个类型来解决这个问题:
(ConfigurationElementCollection< ParentedConfigElement< TParent>,TParent>)this;
不幸的是,我得到了相同的编译器错误。这是为什么发生?我做错了什么?并且,如果不诉诸
动态
类型,我该怎么办才能解决这个问题? 解决方案
你的问题是你有一个类型 不使用隐式运算符或动态的干净解决方案是使用接口: Targeting .net 4.0, I'm trying to build the following classes: As the code comment above indicates, the compiler gives an error: I don't expect this error, because the compiler also knows that Still, I figure I will expressly cast the type to get past this issue: Unfortunately, I get the same compiler error. Why is this happening? What did I do wrong? And without resorting to Your problem is that you have a type A clean solution without using implicit operators or dynamic is to use an interface: Since the property in 这篇关于类型受限的C#类型无效转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! CEC< A,B>
,并且你试图将它分配给 CEC< C< ;不能像
List< string>
那样执行类似存储类型的操作,A>,B> 列表< object>
即使 string 从
object
派生。
public interface IConfigurationElementCollection< TParentedConfig,TParent>
是内部的,你也可以使接口成为内部的,以避免将这个实现细节暴露给任何消费者,如果这种事情是你关心的话。
其中TParentedConfig:ParentedConfigElement< TParent>
其中TParent:class
{
TParent ParentElement {get; }
}
public class ConfigurationElementCollection< TElement,TParent> :IConfigurationElementCollection< ParentedConfigElement< TParent>,TParent>
where TElement:ParentedConfigElement< TParent> ;, new()
其中TParent:class
{
public TParent ParentElement {get;组; }
protected ConfigurationElement CreateNewElement()
{
// ************************* *************************
//编译器不再提供类型转换错误
//因为这实现了预期的接口!
// ******************************************** ******
返回新的TElement {ParentCollection = this};
}
}
公共类ParementedConfigElement< TParent> :ConfigurationElement其中TParent:class
{
internal IConfigurationElementCollection< ParentedConfigElement< TParent>,TParent>
ParentCollection {get;组; }
保护TParent父母
{
获得
{
返回ParentCollection!= null? ParentCollection.ParentElement:null;
$ p $ <$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ code> ParentedConfigElement public class ConfigurationElementCollection<TElement, TParent>
where TElement : ParentedConfigElement<TParent>, new()
where TParent : class
{
public TParent ParentElement { get; set; }
protected ConfigurationElement CreateNewElement()
{
//**************************************************
//COMPILER GIVES TYPE CONVERSION ERROR ON THIS LINE!
//**************************************************
return new TElement { ParentCollection = this };
}
}
public class ParentedConfigElement<TParent> : ConfigurationElement where TParent : class
{
internal ConfigurationElementCollection<ParentedConfigElement<TParent>, TParent>
ParentCollection { get; set; }
protected TParent Parent
{
get
{
return ParentCollection != null ? ParentCollection.ParentElement : null;
}
}
}
Cannot implicitly convert type 'Shared.Configuration.ConfigurationElementCollection<TElement, TParent>' to 'Shared.Configuration.ConfigurationElementCollection<Shared.Configuration.ParentedConfigElement<TParent>,TParent>
TElement
is a Shared.Configuration.ParentedConfigElement<TParent>
due to the generic type constraint I specified.(ConfigurationElementCollection<ParentedConfigElement<TParent>,TParent>) this;
dynamic
types, what can I do to fix this?CEC<A, B>
and you trying to assign it to a property of type CEC<C<A>,B>
which you can't do, in much the same way as List<string>
cannot be assigned to storage of type List<object>
even though string
derives from object
.public interface IConfigurationElementCollection<TParentedConfig, TParent>
where TParentedConfig : ParentedConfigElement<TParent>
where TParent : class
{
TParent ParentElement { get; }
}
public class ConfigurationElementCollection<TElement, TParent> : IConfigurationElementCollection<ParentedConfigElement<TParent>, TParent>
where TElement : ParentedConfigElement<TParent>, new()
where TParent : class
{
public TParent ParentElement { get; set; }
protected ConfigurationElement CreateNewElement()
{
//**************************************************
//COMPILER NO LONGER GIVES TYPE CONVERSION ERROR
//BECAUSE this IMPLEMENTS THE EXPECTED INTERFACE!
//**************************************************
return new TElement { ParentCollection = this };
}
}
public class ParentedConfigElement<TParent> : ConfigurationElement where TParent : class
{
internal IConfigurationElementCollection<ParentedConfigElement<TParent>, TParent>
ParentCollection { get; set; }
protected TParent Parent
{
get
{
return ParentCollection != null ? ParentCollection.ParentElement : null;
}
}
}
ParentedConfigElement
is internal, you can also make the interface internal to avoid exposing this implementation detail to any consumers, if that sort of thing is a concern for you.