类型受限的C#类型无效转换 [英] Invalid Cast of Type Constrained C# Generic

查看:137
本文介绍了类型受限的C#类型无效转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

$ p
$ 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; 

不幸的是,我得到了相同的编译器错误。这是为什么发生?我做错了什么?并且,如果不诉诸动态类型,我该怎么办才能解决这个问题? 解决方案

你的问题是你有一个类型 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
是内部的,你也可以使接口成为内部的,以避免将这个实现细节暴露给任何消费者,如果这种事情是你关心的话。

Targeting .net 4.0, I'm trying to build the following classes:

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

As the code comment above indicates, the compiler gives an error:

Cannot implicitly convert type 'Shared.Configuration.ConfigurationElementCollection<TElement, TParent>' to 'Shared.Configuration.ConfigurationElementCollection<Shared.Configuration.ParentedConfigElement<TParent>,TParent>

I don't expect this error, because the compiler also knows that TElement is a Shared.Configuration.ParentedConfigElement<TParent> due to the generic type constraint I specified.

Still, I figure I will expressly cast the type to get past this issue:

(ConfigurationElementCollection<ParentedConfigElement<TParent>,TParent>) this;

Unfortunately, I get the same compiler error. Why is this happening? What did I do wrong? And without resorting to dynamic types, what can I do to fix this?

解决方案

Your problem is that you have a type 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.

A clean solution without using implicit operators or dynamic is to use an interface:

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

Since the property in 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.

这篇关于类型受限的C#类型无效转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆