4

I have this peace of code in a console app .net core 3.1 on VS 16.5.1:

namespace DefaultInterfaceTest
{
    class Program
    {
        static void Main(string[] args)
        {   
            var person = new Person();
            person.GetName();//error here
        }
    }

    public interface IPerson
    {
        string GetName()
        {
            return "Jonny";
        }
    }

    public class Person: IPerson
    {

    }
}

I was hopping I could access the default implementation oif GetName from the person itself, as it's a public method but it yields this error:

'Person' does not contain a definition for 'GetName' and no accessible extension method 'GetName' accepting a first argument of type 'Person' could be found (are you missing a using directive or an assembly reference?)

How can I access the default implementation of an interface from outside code or from the Person class itself? Thanks!

ADyson
  • 57,178
  • 14
  • 51
  • 63
Fritjof Berggren
  • 3,178
  • 5
  • 35
  • 57

2 Answers2

7

You can only access default implementation methods by calling via an interface reference (think of them as explicitly implemented methods).

For example:

// This works
IPerson person = new Person();
person.GetName();

But:

// Doesn't works
Person person = new Person();
person.GetName();

If you want to call the default interface method from within your class then you'll need to cast this to an IPerson in order to do so:

private string SomeMethod()
{
  IPerson self = this;
  return self.GetName();
}

There's no way around the case if you are using interfaces. If you really want this sort of behavior then you'll need to use an abstract class where GetName is a virtual method.

abstract class PersonBase
{
  public virtual string GetName()
  {
    return "Jonny";
  }
}
Sean
  • 60,939
  • 11
  • 97
  • 136
  • Yes, but I want the later to work, because I need some methods to have access to the full person object, not only to the default interface one – Fritjof Berggren Mar 26 '20 at 09:34
  • 1
    @FritjofBerggren - You're out of luck. Can you use a base class instead? – Sean Mar 26 '20 at 09:35
  • That's why I was using interfaces, because I have to inherit for another base class :( Can I call this GetName method from inside the Person object? – Fritjof Berggren Mar 26 '20 at 09:36
  • @FritjofBerggren - You can call if from inside, but you'll have to cst `this` to an `IPerson` in order to make the call. – Sean Mar 26 '20 at 09:39
  • @FritjofBerggren Is `IPerson f = person; f.GetName()` not suite for you? It still holds the instance. – Louis Go Mar 26 '20 at 09:39
  • I have some other methods inside the Person class, and I don't want to be casting to IPerson to access some methods and holding a reference to a Person to access others, looks nasty. – Fritjof Berggren Mar 26 '20 at 09:40
  • I'd like to avoid this: public class Person: IPerson { public Person() { var name = ((IPerson)this).GetName(); } } – Fritjof Berggren Mar 26 '20 at 09:41
  • Don't know why if my instance is implementing an interface, can't call the default method from itself – Fritjof Berggren Mar 26 '20 at 09:42
  • @FritjofBerggren - I agree, it does look strange, but it's your only optionif you want to access the method using interfaces rather than base classes. – Sean Mar 26 '20 at 09:42
  • I think I'm going to move the code to a static class and use static imports, so It looks like it's from the class. – Fritjof Berggren Mar 26 '20 at 10:02
1

is casting something you can use in your situation?

using System;

namespace DefaultInterfaceTest
{
    class Program
    {
        static void Main(string[] args)
        {   
            IPerson person = new Person();

            Person fooPerson = (Person) person;
            Console.WriteLine(person.GetName());
            Console.WriteLine(fooPerson.Foo());
        }
    }

    public interface IPerson
    {
        public string GetName()
        {
            return "Jonny";
        }
    }

    public class Person: IPerson
    {
      public string Foo()
      {
           return "Hello";
      }
    }
}
beniutek
  • 1,672
  • 15
  • 32
  • That's what I want to avoid doing, casting and object when that object is suppose to implement a default interface. I should have access to it from the base class I think. – Fritjof Berggren Mar 26 '20 at 09:48