简体   繁体   English

通用接口类型转换问题

[英]Generic Interface type conversion issues

I have been battling with this bit of code for a while now and I am trying to get a solution as it is literally the last part before it goes to testing. 我一直在与这段代码作斗争一段时间,而我正试图找到一种解决方案,因为它实际上是测试之前的最后一部分。

I have the following interfaces and classes (simplified to the relevant parts): 我有以下接口和类(简化为相关部分):

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

I am trying to use the GetTagCurrentValue method in the TagAddOnManager class like this: 我试图像这样在TagAddOnManager类中使用GetTagCurrentValue方法:

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

Everything compiles fine, but errors when trying to cast gridCell.Row.Data to ITagParent<ITag> . 一切编译正常,但是尝试将gridCell.Row.DataITagParent<ITag> I understand this is due to covarience and a workaround (if not a terribly safe one) is to mark T in the ITagParent interface with the out keyword, but that won't work as you can see it is used in the TagCollection property, which can't be read only. 我知道这是由于协方差造成的,一种变通方法(如果不是非常安全的方法)是使用out关键字在ITagParent接口中标记T ,但是这种方法不起作用,因为您可以看到TagCollection属性中使用了T,不能是只读的。

I tried casting the above to ITagParent<CustomerTag> , but this fails at compile time with a 'cannot convert' error when trying to feed it into my GetTagCurrentValue method. 我尝试将上面的内容强制转换为ITagParent<CustomerTag> ,但这在编译时失败,并在尝试将其输入到GetTagCurrentValue方法时出现“无法转换”错误。

Another option I considered is using some base classes instead of the ITagParent interface, but that won't work as the Customer object already inherits from another base class, which can't be modified for this implementation. 我考虑过的另一种选择是使用一些基类而不是ITagParent接口,但是该方法不起作用,因为Customer对象已经从另一个基类继承,因此无法为该实现进行修改。

I know I could just overload the GetTagCurrentValue method with List<TagAddOn<CustomerTag>> as the parameter type and all other variations, but that really seems like a 'I give up' solution. 我知道我可以使用List<TagAddOn<CustomerTag>>作为参数类型和所有其他变体来重载GetTagCurrentValue方法,但这确实是一个“我放弃”的解决方案。 I could probably use reflection to get the desired results, but that would be unwieldy and not very efficient, especially considering this method could be called a lot in a particular process. 我可能可以使用反射来获得所需的结果,但这将很麻烦并且效率不高,尤其是考虑到该方法在特定过程中可能被称为很多方法。

So does anyone have any suggestions? 那么有人有什么建议吗?

Could you use something like that 你能用这样的东西吗

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

and use it like that?` 并像那样使用它?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM