简体   繁体   中英

How to call a method defined in interface and implemented in class in C#?

I have an interface file named IAp.cs and it implements the following interface:

public interface IAp
{
    Output Process(double min, double max, IEnumerable<string> items);
}

Then, I have a class defined like this:

[Export(typeof(IAp))]
public class Ap : IAp
{
    readonly ISorter _sorter;

    public Ap()
    {
        _sorter = ContainerProvider.Container.GetExportedValue<ISorter>();
    }

    Output IAp.Process(double min, double max, IEnumerable<string> items) 
    {
       // rest removed for brevity
    }
}

The ISorter interface, and the ContainerProvider class is defined as follows, but in separate files:

interface ISorter
{
    string Sort(string token);
}

internal static class ContainerProvider
{
    private static CompositionContainer container;

    public static CompositionContainer Container
    {
        get
        {
            if (container == null)
            {
                List<AssemblyCatalog> catalogList = new List<AssemblyCatalog>();
                catalogList.Add(new AssemblyCatalog(typeof(ISorter).Assembly));
                container = new CompositionContainer(new AggregateCatalog(catalogList));
            }

            return container;
        }
    }
}

Now, inside another source file, I want to call the Process method. I did something like this:

private readonly IAp _ap;
Output res = _ap.Process(50, 100, items);

But this says that _ap is never assigned to, and it is null, therefore it doesn't call the Process method. It throws NullReference error.

I also tried initializing the class as below:

private Ap app = new Ap();

But then, if I do app. to access its members, it doesn't find the Process method, it is not there. Any ideas how to call the Process method in another source file and class?

You need to instantiate the class and then hold it's reference as interface type (as Ap is inheriting from interface IAp so it is legal because of polymorphism ) like:

private readonly IAp _ap =  new Ap();
Output res = _ap.Process(50, 100, items);
private IAp app = new Ap();

This is because Ap implements IAp . The reason that you cant do what you were trying to do is because you were using an explicit interface implementation, the interface method is only visible on a reference to the interface and not the class.

See Explicit Interface Implementation Tutorial for details on explicit interface implementations.

The other work around is to not use explicit interface implementation but this could leave you referencing the type directly which is usually not considered best practice.

Code only showing changed signature implementation.

public class Ap : IAp
{
    public Output Process(double min, double max, IEnumerable<string> items) 
    {
       // rest removed for brevity
    }
}

Now using your existing reference would also work.

For further information please also refer to Interfaces - C# Programming Guide

The behavior you are seeing is because the interface is explicitly implemented. You need to do one the following:

  1. Assign the App instance to an IAp typed variable:

     IAp _ap = new Ap(); //now you can do _app.Process 
  2. Implement the interface implicitly:

     public class Ap: IAp { public Output Process(....) { ... } } Ap _ap = new Ap(); //now you can do _ap.Process 

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