简体   繁体   English

C#从父接口继承属性

[英]C# Inheriting properties from parent interface

I'm trying to mock up a data access library for Neo4J in .NET 4.5. 我正在尝试在.NET 4.5中为Neo4J模拟数据访问库。 I am using interfaces to define each command to the database. 我使用接口来定义数据库的每个命令。

Given: 鉴于:

    public interface IBaseRequest 
    {
        HttpMethod HttpMethod { get; }    
        string QueryUriSegment { get; }    
    }

    public interface ICreateNode  : IBaseRequest
    {
        void CreateNode();

    }

    public interface IBaseNodeActions  : ICreateNode,ICreateNodeWProperties //...And many others, all inherit from IBaseRequest
    {
    }

    internal class TestImplClass : IBaseNodeActions {


        public TestImplClass() {


        }
        void ICreateNode.CreateNode() {
            throw new NotImplementedException();
        }
        //Only one copy of the HttpMethod and QueryUriSegment are able to be implemented
        DataCommands.HttpHelper.HttpMethod IBaseRequest.HttpMethod {
            get {
                throw new NotImplementedException();
            }
        }

        string IBaseRequest.QueryUriSegment {
            get {
                throw new NotImplementedException();
            }
        }

Problem is for each interface that inherits from IBaseRequest, I need a property implemented for each property that it's parent owns (HttpMethod, QueryUriSegment). 问题是从IBaseRequest继承的每个接口,我需要为它的父拥有的每个属性实现的属性(HttpMethod,QueryUriSegment)。

Is this possible? 这可能吗? I know that using explicit implementation will be necessary but not sure how to push those into the implementing class. 我知道使用显式实现是必要的,但不确定如何将它们推入实现类。

Here is what I'd like to see in my implementing class: 以下是我希望在我的实现课程中看到的内容:

public class TestImplClass : IBaseNodeActions{
public TestImplClass() {


        }
        void ICreateNode.CreateNode() {
            throw new NotImplementedException();
        }

        HttpMethod ICreateNode.HttpMethod {
            get {
                throw new NotImplementedException();
            }
        }

        string ICreateNode.QueryUriSegment {
            get {
                throw new NotImplementedException();
            }
        }
        HttpMethod ICreateNodeWProperties.HttpMethod {
            get {
                throw new NotImplementedException();
            }
        }

        string ICreateNodeWProperties.QueryUriSegment {
            get {
                throw new NotImplementedException();
            }
        }
}

Notice the ICreateNode and ICreateNodeWProperties instead of the IBaseRequest. 注意ICreateNode和ICreateNodeWProperties而不是IBaseRequest。 I'm open to doing it differently but it seems like a modular, testable approach. 我愿意采用不同的方式,但它似乎是一种模块化,可测试的方法。

I hope that makes sense! 我希望这是有道理的!

You could define an abstract BaseRequest Class. 您可以定义一个抽象的BaseRequest类。 That one implementing the IBaseRequest properties. 那个实现IBaseRequest属性。

So, the classes implementing all child interfaces would inherit this BaseRequest and have the properties automatically implemented. 因此,实现所有子接口的类将继承此BaseRequest并自动实现属性。

Forgive if I misunderstood exactly what you were looking for. 如果我误解了你在找什么,请原谅。

You could have a base class: 你可以有一个基类:

public abstract class BaseNodeActions : IBaseNodeActions
{
    public abstract void CreateNode();
    public abstract HttpMethod HttpMethod {get;set;}
    ....
}

Then just make your TestImplClass inherit BaseNodeActions 然后让你的TestImplClass继承BaseNodeActions

If you want, you could also ignore using abstract and do the following: 如果需要,您也可以忽略使用抽象并执行以下操作:

public class BaseNodeActions : IBaseNodeActions
{
    public virtual void CreateNode() { throw new NotImplementedException(); }
    public virtual HttpMethod HttpMethod {get { throw new NotImplementedException(); }
    ....
}

If you make the properties virtual, you will only need to override the ones you actually need. 如果将属性设置为虚拟,则只需覆盖实际需要的属性。 You may want to remove the throwing of exceptions and make it return default values if your design allows for it. 如果您的设计允许,您可能希望删除抛出异常并使其返回默认值。

It's not possible to do what you intend with interfaces. 你不可能做你想要的接口。 As you've seen, when a class implements two or more interfaces which themselves inherit a common interface, the common interface is implicitly added, but only once - you don't get a variant of the base interface for each derived interface. 正如您所见,当一个类实现两个或多个接口本身继承一个公共接口时,公共接口被隐式添加,但只有一次 - 您没有为每个派生接口获得基接口的变体。

You could try the following (based on the Command pattern ): 您可以尝试以下(基于命令模式 ):

interface ICommand {
    HttpMethod HttpMethod { get; }    
    string QueryUriSegment { get; }

    void Execute();
}

class abstract BaseCommand : ICommand {
    public abstract HttMethod { get; }
    public abstract string QueryUriSegment { get; }
}

class CreateNodeCommand : ICommand {
    public override HttpMethod HttpMethod { get { /* return HttpMethod for "create node" */ } }
    public override string QueryUriSegment { get { /* return QueryUriString for "create node" */ } }

    public void Execute() { /* Create node... */ }
}

class CreateNodeWithPropertiesCommand : ICommand {
    public override HttpMethod HttpMethod { get { /* return HttpMethod for "create node with properties" */} }
    public override string QueryUriSegment { get { /* return QueryUriString for "create node with properties" */ } }

    public void Execute() { /* Create node with properties ... */ }
}

In your TestImplClass you can have each command as a separate property: 在TestImplClass中,您可以将每个命令作为单独的属性:

public TestImplClass {
    public ICommand CreateNode { get; private set; }
    public ICommand CreateNodeWithProperties { get; private set; }

    public TestImplClass(ICommand createNode, ICommand createNodeWithProperties) {
        this.CreateNode = createNode;
        this.CreateNodeWithProperties = createNodeWithProperties;
    }
}

Each command then has it's own HttpMethod and QueryUriSegment properties and you can mock each command and pass them into the constructor of TestImplClass when testing. 然后,每个命令都有自己的HttpMethod和QueryUriSegment属性,您可以在测试时模拟每个命令并将它们传递给TestImplClass的构造函数。

When it comes to using any of the commands you can just call Execute() on the appropriate property eg: dataAccess.CreateNode.Execute(); 在使用任何命令时,您只需在相应的属性上调用Execute() ,例如: dataAccess.CreateNode.Execute(); .

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

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