通用接口类型转换问题

时间:2014-04-15 14:31:42

标签: c# generics interface

我一直在与这段代码进行斗争已经有一段时间了,我正试图找到一个解决方案,因为它确实是它进入测试之前的最后一部分。

我有以下接口和类(简化为相关部分):

public interface ITagParent<T> where T : ITag
{
    List<TagAddOn<T>> TagCollection { get; set; }
}

public interface ITag
{
    int Id { get; set; }
    string Description { get; set; }
    TagGroup TagGroup { get; set; }
}

public class TagAddOn<T> : ViewModelBase where T : ITag
{
    private T _currentTag;
    public T CurrentTag
    {
        get { return _currentTag; }
        set { _currentTag = value; }
    }
}

public partial class Customer : ITagParent<CustomerTag>
{
    List<TagAddOn<CustomerTag>> _tagCollection;
    public List<TagAddOn<CustomerTag>> TagCollection
    {
        get { return _tagCollection; }
        set { _tagCollection = value; }
    }
}

public partial class CustomerTag : ITag
{
    public int Id { get; set; }
}

public class TagAddOnManager
{
    public static string GetTagCurrentValue(List<TagAddOn<ITag>> dataObjectAddOns)
    {
        // LOTS OF SNIPPING!
        return string.Empty;
    }
}

我正在尝试使用GetTagCurrentValue类中的TagAddOnManager方法,如下所示:

string value = TagAddOnManager.GetTagCurrentValue(
    ((ITagParent<ITag>)gridCell.Row.Data).TagCollection));

在尝试将gridCell.Row.Data投射到ITagParent<ITag>时,所有内容都可以正常编译,但会出错。我理解这是由于协变性和一种解决方法(如果不是非常安全的话)是使用T关键字在ITagParent界面中标记out,但这不是正如您所看到的那样,它在TagCollection属性中使用,该属性不能只读。

我尝试将上述内容转换为ITagParent<CustomerTag>,但是在编译时失败并且无法转换&#39;尝试将其提供给我的GetTagCurrentValue方法时出错。

我考虑的另一个选项是使用一些基类而不是ITagParent接口,但由于Customer对象已经从另一个基类继承而无法工作,因此可以使用#{1}}接口。为此实施进行修改。

我知道我可以使用GetTagCurrentValue作为参数类型和所有其他变体来重载List<TagAddOn<CustomerTag>>方法,但这看起来像是“我放弃了”#39;解。我可能会使用反射来获得所需的结果,但这样做会很笨拙并且效率不高,特别是考虑到这种方法在特定的过程中可以被调用很多。

那么有人有任何建议吗?

1 个答案:

答案 0 :(得分:1)

你可以使用类似的东西

public class TagAddOnManager
{
    public static string GetTagCurrentValue<TTag>(ITagParent<TTag> tagParent)
        where TTag : ITag
    {
        // Just an example.
        return tagParent.TagCollection.First().CurrentTag.Description;
    }
}

并像那样使用它?`

var value = TagAddOnManager.GetTagCurrentValue((Customer)CustomergridCell.Row.Data);