简体   繁体   English

接口无法解析参数类型

[英]Interface not resolving for parameter type

I have the following classes: 我有以下课程:

namespace CommonInterfaces
{
    public interface INode
    {
        int? ParentNodeId { get; set; }
        int? ChildNodeId { get; set; }
    }
}

public class FieldDependencyModel : DataModel<int>, ICacheable
{

    #region Field

    private int _FieldDependencyId;
    private int? _FieldId;
    private int? _FieldParentId;

    #endregion  

    #region Properties

    public virtual int FieldDependencyId
    {
        get { return getPropertyValue("FieldDependencyId",_FieldDependencyId); }
        set { _FieldDependencyId = value; }
    }

    public virtual int? ChildNodeId
    {
        get { return getPropertyValue("FieldId",_FieldId); }
        set { _FieldId = value; }
    }

    public virtual int? ParentNodeId
    {
        get { return getPropertyValue("FieldParentId",_FieldParentId); }
        set { _FieldParentId = value; }
    }

    #endregion
}


    public interface IFieldDependencyService
    {
        IList<FieldDependency> GetAllFieldDependencies();
    }

    public class FieldDependency : FieldDependencyModel, INode
    {
    }


    public class FieldDependencyDataService : BaseDataService, IFieldDependencyService
    {
        public FieldDependencyDataService(DataAccessHandle serviceHandler) : base(serviceHandler) {}

        public IList<FieldDependency> GetAllFieldDependencies()
        {
            return _accessService.loadAll<FieldDependency>();
        }
    }

    public class TreeService
    {
        private IList<INode> _relationships;
        private INode _rootNode;    


        public TreeService(INode rootNode, IList<INode> nodeRelationships)
        {
            _relationships = nodeRelationships;
            _rootNode = rootNode;
        }


        public Tree<INode> BuildTree()
        {
            Tree<INode> tree;

            tree = new Tree<INode>(_rootNode, _relationships);

            return tree;
        }
    }

I try sending in a type which impliments INode and it still says the following error when I try passing in the fieldDependencies to the new TreeService instantiation: 我尝试发送一种隐含INode的类型,当我尝试将fieldDependencies传递给新的TreeService实例时,它仍然显示以下错误:

Error   5   Argument 2: cannot convert from 'System.Collections.Generic.IList<FieldDependency>' to 'System.Collections.Generic.IList<CommonInterfaces.INode>'   

Here's my calling code where I get this error: 这是我收到此错误的调​​用代码:

            IList<FieldDependency> fieldDependencies = _service.GetAllFieldDependencies();

            FieldDependency rootDependency = fieldDependencies.First(d => d.ParentNodeId == null);
 var service = new TreeService(rootDependency, fieldDependencies); // fails here, doesn't like fieldDependencies

Try this 尝试这个

IList<INode> fieldDependencies = _service.GetAllFieldDependencies()
.First(d => d.ParentNodeId == null).Select(d => (INode)d);

You can't do that because you're trying to convert an IList<FieldDependency> to an IList<INode> , so the actual object you're trying to convert is the IList that have the related types as their generic types. 您无法执行此操作,因为您试图将IList<FieldDependency>转换为IList<INode> ,因此您要转换的实际对象是具有相关类型作为其通用类型的IList There are a few courses of action you can take to get around this. 您可以采取一些行动来解决此问题。

Replace IList<FieldDependency> with IList<INode> IList<FieldDependency>替换为IList<INode>

You could change your code so that the IList<FieldDependency> is an IList<INode> . 您可以更改代码,使IList<FieldDependency>IList<INode>

public interface IDataFieldDependencyService
{
    IList<INode> GetAllFieldDependencies();
}

public class FieldDependencyDataService : BaseDataService, IFieldDependencyService
{
    public FieldDependencyDataService(DataAccessHandle serviceHandler) : base(serviceHandler) {}

    public IList<INode> GetAllFieldDependencies()
    {
        return _accessService.loadAll<FieldDependency>();
    }
}

Usage 用法

IList<INode> fieldDependencies = _service.GetAllFieldDependencies();

INode rootDependency = fieldDependencies.First(d => d.ParentNodeId == null);
var service = new TreeService(rootDependency, fieldDependencies);

Select and cast as INode Select并转换为INode

You could also select all the elements from _service.GetAllFieldDependencies() and box them in INode . 您还可以从_service.GetAllFieldDependencies()中选择所有元素,然后将其放在INode

IList<INode> fieldDependencies = _service.GetAllFieldDependencies()
    .Select(e => (INode)e)
    .ToList();

INode rootDependency = fieldDependencies.First(d => d.ParentNodeId == null);
var service = new TreeService(rootDependency, fieldDependencies);

Covariance 协方差

If you work with IEnumerable s then you can probably do what you want using covariance (.NET 4 I believe). 如果使用IEnumerable s,则可能可以使用协方差 (我相信.NET 4)来做您想做的事情。

public class TreeService
{
    private IEnumerable<INode> _relationships;
    private INode _rootNode;    


    public TreeService(INode rootNode, IEnumerable<INode> nodeRelationships)
    {
        _relationships = nodeRelationships;
        _rootNode = rootNode;
    }


    public Tree<INode> BuildTree()
    {
        Tree<INode> tree;

        tree = new Tree<INode>(_rootNode, _relationships);

        return tree;
    }
}

Usage 用法

IEnumerable<INode> fieldDependencies = _service.GetAllFieldDependencies();

INode rootDependency = fieldDependencies.First(d => d.ParentNodeId == null);
var service = new TreeService(rootDependency, fieldDependencies);

You have defined field dependencies as a list of FieldDependency, ie 您已经将字段依赖项定义为FieldDependency的列表,即

fieldDependencies.GetType() == typeof<IList<FieldDependency>>

the TreeService constructor's 2nd parameter expects tyepof(IList<INode>>) TreeService构造函数的第二个参数期望tyepof(IList<INode>>)

you should be able to just change the way you define the variable fieldDependencies as IList<INode> 您应该能够更改将变量fieldDependencies定义为IList<INode>

ie

IList<INode> fieldDependencies = _service.GetAllFieldDependencies()

Try 尝试

var service = new TreeService(rootDependency, fieldDependencies.Cast<INode>().ToList());

Having class B derived from class A does not guarantee that you will be able to cast object generic collection type with type parameter B to generic collection type with type parameter A. 具有从类A派生的类B不能保证您将能够将类型参数B的对象通用集合类型转换为类型参数A的通用集合类型。

You can read more about contravariance here and here . 您可以在这里这里阅读更多有关自变量的信息

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

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