typos
typos

Reputation: 6632

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?

Upvotes: 0

Views: 4174

Answers (3)

Igor
Igor

Reputation: 62213

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

Upvotes: 4

InBetween
InBetween

Reputation: 32750

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
    

Upvotes: 1

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

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);

Upvotes: 4

Related Questions