类型约束C#Generic的无效转换

前端之家收集整理的这篇文章主要介绍了类型约束C#Generic的无效转换前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_403_0@
针对.net 4.0,我正在尝试构建以下类:
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;
        }
    }
}

正如上面的代码注释所示,编译器给出了一个错误

无法隐式转换类型’Shared.Configuration.ConfigurationElementCollection< TElement,TParent>‘ ‘Shared.Configuration.ConfigurationElementCollection< Shared.Configuration.ParentedConfigElement< TParent>,TParent>

我不指望这个错误,因为编译器也知道TElement是Shared.Configuration.ParentedConfigElement< TParent>由于我指定的泛型类型约束.

不过,我想我会明确地说出这个类型来解决这个问题:

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

不幸的是,我得到了相同的编译器错误.为什么会这样?我做错了什么?如果不采用动态类型,我该怎么做才能解决这个问题?

解决方法

你的问题是你有一个类型CEC< A,B>并且您尝试将其分配给CEC类型的属性< C< A>,B>这是你不能做的,与List< string>的方式大致相同.无法分配到List< 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中的属性是内部属性,因此您还可以将接口设置为内部,以避免将此实现细节暴露给任何使用者,如果您担心这种情况.

原文链接:https://www.f2er.com/c/119540.html

猜你在找的C&C++相关文章