我一直在与这段代码进行斗争已经有一段时间了,我正试图找到一个解决方案,因为它确实是它进入测试之前的最后一部分。
我有以下接口和类(简化为相关部分):
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;解。我可能会使用反射来获得所需的结果,但这样做会很笨拙并且效率不高,特别是考虑到这种方法在特定的过程中可以被调用很多。
那么有人有任何建议吗?
答案 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);