简体   繁体   中英

How can I implement an interface type using a explicit class

I have the following interfaces:

public interface IReplaceable
{
    int ParentID { get; set; }

    IReplaceable Parent { get; set; }
}

public interface IApproveable
{
    bool IsAwaitingApproval { get; set; }

    IApproveable Parent { get; set; }
}

I would like to implement it in the class like so:

public class Agency :  IReplaceable, IApproveable
{
     public int AgencyID { get; set; }
     // other properties

     private int ParentID { get; set; }

     // implmentation of the IReplaceable and IApproveable property
     public Agency Parent { get; set; }
}

Is there any way that I can do this?

You can't implement an interface with a method (or property) that doesn't satisfy the interface's signature. Consider this:

IReplaceable repl = new Agency();
repl.Parent = new OtherReplaceable(); // OtherReplaceable does not inherit Agency

How should the type checker evaluate this? It would be valid by the signature of IReplaceable , but not by the signature of Agency .

Instead, consider using explicit interface implementation like this:

public class Agency : IReplaceable
{
    public int AgencyID { get; set; }
    // other properties

    private int ParentID { get; set; }

    public Agency Parent { get; set; }

    IReplaceable IReplaceable.Parent
    {
        get 
        {
            return this.Parent;          // calls Agency Parent
        }
        set
        {
            this.Parent = (Agency)value; // calls Agency Parent
        }
    }

    IApproveable IApproveable.Parent
    {
        get 
        {
            return this.Parent;          // calls Agency Parent
        }
        set
        {
            this.Parent = (Agency)value; // calls Agency Parent
        }
    }
}

Now, when you do something like this:

IReplaceable repl = new Agency();
repl.Parent = new OtherReplaceable();

The type checker considers this valid by the signature of the IReplaceable , so it compiles just fine, but it would throw an InvalidCastException at run time (of course, you can implement your own logic if you don't want an exception). However, if you do something like this:

Agency repl = new Agency();
repl.Parent = new OtherReplaceable();

It will not compile, because the type checker will know that repl.Parent must be an Agency .

You can implement it explicitly . That's why they exist.

public class Agency : IReplaceable, IApproveable
{
    public int AgencyID { get; set; }

    int IReplaceable.ParentID
    {
        get;
        set;
    }

    bool IApproveable.IsAwaitingApproval
    {
        get;
        set;
    }

    IApproveable IApproveable.Parent
    {
        get;
        set;
    }

    IReplaceable IReplaceable.Parent
    {
        get;
        set;
    }
}

Sadly you can't access it via class instance, you need to cast it to interface in order to use them.

Agency agency = ...;
agency.Parent = someIApproveable;//Error
agency.Parent = someIReplaceable;//Error
((IApproveable)agency).Parent = someIApproveable;//Works fine
((IReplaceable)agency).Parent = someIReplaceable;//Works fine

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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