Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Interface with a default implementation

Interface with a default implementation

Scheduled Pinned Locked Moved C#
debugginghelpquestion
13 Posts 5 Posters 36 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Richard Andrew x64R Richard Andrew x64

    Thanks Luc. If you say it's complex, then it must be too far for me to grasp. ;) I've decided to use the IClientFormHelper class as an extension method call, that I will just have to repeat in my IClientForm window classes.

    The difficult we do right away... ...the impossible takes slightly longer.

    L Offline
    L Offline
    Luc Pattyn
    wrote on last edited by
    #4

    Hm. The one link shows there are many aspects to the default implementation inside interfaces, that article is hard to read and understand in one go. The first answer in the SO link shows how a default property getter could be written; that is simple, and at first glance what you want could be implemented likewise as a default setter. :)

    Luc Pattyn [My Articles] The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.

    Richard Andrew x64R 1 Reply Last reply
    0
    • L Luc Pattyn

      Hm. The one link shows there are many aspects to the default implementation inside interfaces, that article is hard to read and understand in one go. The first answer in the SO link shows how a default property getter could be written; that is simple, and at first glance what you want could be implemented likewise as a default setter. :)

      Luc Pattyn [My Articles] The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.

      Richard Andrew x64R Offline
      Richard Andrew x64R Offline
      Richard Andrew x64
      wrote on last edited by
      #5

      That's one of the major things that stumped me. Since an interface can't contain data members, then if I try to write a default setter, I have nothing to assign it to. It was at that point that I gave up! EDIT: Maybe I should solve the problem by using the inheritance of a base class, rather than trying to stuff it into the interface. That gives me an idea...

      The difficult we do right away... ...the impossible takes slightly longer.

      L 1 Reply Last reply
      0
      • Richard Andrew x64R Richard Andrew x64

        That's one of the major things that stumped me. Since an interface can't contain data members, then if I try to write a default setter, I have nothing to assign it to. It was at that point that I gave up! EDIT: Maybe I should solve the problem by using the inheritance of a base class, rather than trying to stuff it into the interface. That gives me an idea...

        The difficult we do right away... ...the impossible takes slightly longer.

        L Offline
        L Offline
        Luc Pattyn
        wrote on last edited by
        #6

        You could use properties rather than variables, couldn't you? That is what the example does... :)

        Luc Pattyn [My Articles] The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.

        Richard Andrew x64R 1 Reply Last reply
        0
        • L Luc Pattyn

          You could use properties rather than variables, couldn't you? That is what the example does... :)

          Luc Pattyn [My Articles] The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.

          Richard Andrew x64R Offline
          Richard Andrew x64R Offline
          Richard Andrew x64
          wrote on last edited by
          #7

          Yes I could use properties, but at some point in the call stack, the value must be assigned to a data member in the window instance. So that's code that must be repeated in each class, unless I derive from a base class.

          The difficult we do right away... ...the impossible takes slightly longer.

          L 1 Reply Last reply
          0
          • Richard Andrew x64R Richard Andrew x64

            Yes I could use properties, but at some point in the call stack, the value must be assigned to a data member in the window instance. So that's code that must be repeated in each class, unless I derive from a base class.

            The difficult we do right away... ...the impossible takes slightly longer.

            L Offline
            L Offline
            Luc Pattyn
            wrote on last edited by
            #8

            Ah, sorry, I missed the sentence "You can't declare auto-implemented properties in interfaces" in Auto-Implemented Properties - C# | Microsoft Learn[^] . Makes sense. :)

            Luc Pattyn [My Articles] The Windows 11 taskbar is a disgrace; a third-party add-on is needed to reverse the deterioration. I decline such a downgrade.

            1 Reply Last reply
            0
            • Richard Andrew x64R Richard Andrew x64

              I'm having trouble getting my mind around how a default method in an interface works. Picture the below interface and default method implementation:

              public interface IClientForm
              {
                  delegate void WindowClosedDelegate(object sender, WindowEventArgs args);
                  event WindowClosedDelegate OnClosed;
              
                  long FormId { get; set; }
              
                  UIContextClass UIContext { get; set; }
              
                  IClientForm ParentForm { get; set; }
                  void Window\_Closed(object sender, WindowEventArgs args);
              }
              

              // Below is the default method implementation

              public static class IClientFormHelper
              {
                  public static void SetUiContext(this IClientForm iClientForm, UIContextClass \_UiContext)
                  {
                      iClientForm.UIContext = \_UiContext;  // I put a breakpoint here and it's never hit
                      iClientForm.FormId = \_UiContext.AppContext.ClientGetUniqueFormId();
                      iClientForm.UIContext.AddForm(iClientForm);
                      iClientForm.OnClosed += iClientForm.UIContext.Window\_Closed;
                  }
              }
              

              The main problem I see right now is that the default method code never runs. I assume the code is supposed to run as soon as I call the setter for UIContext that's declared in the main interface. Apparently, this is something I don't understand. What I want is for every IClientForm window to run the default code whenever the UIContext setter is called for that form, so that each separate window class doesn't need the same code repeated inside of it. Can someone spot what I've done wrong and point me in the right direction? I sincerely appreciate your time.

              The difficult we do right away... ...the impossible takes slightly longer.

              J Offline
              J Offline
              jschell
              wrote on last edited by
              #9

              Richard Andrew x64 wrote:

              default method in an interface works.

              Default interface methods - C# feature specifications | Microsoft Learn[^] "to add methods to an interface in future versions without breaking source or binary compatibility with existing implementations of that interface." The feature is a hack which should be avoided if possible. It does not fit your case. An abstract class is a better starting point for your example.

              Richard Andrew x64R 1 Reply Last reply
              0
              • J jschell

                Richard Andrew x64 wrote:

                default method in an interface works.

                Default interface methods - C# feature specifications | Microsoft Learn[^] "to add methods to an interface in future versions without breaking source or binary compatibility with existing implementations of that interface." The feature is a hack which should be avoided if possible. It does not fit your case. An abstract class is a better starting point for your example.

                Richard Andrew x64R Offline
                Richard Andrew x64R Offline
                Richard Andrew x64
                wrote on last edited by
                #10

                Thanks for your advice.

                The difficult we do right away... ...the impossible takes slightly longer.

                1 Reply Last reply
                0
                • Richard Andrew x64R Richard Andrew x64

                  I'm having trouble getting my mind around how a default method in an interface works. Picture the below interface and default method implementation:

                  public interface IClientForm
                  {
                      delegate void WindowClosedDelegate(object sender, WindowEventArgs args);
                      event WindowClosedDelegate OnClosed;
                  
                      long FormId { get; set; }
                  
                      UIContextClass UIContext { get; set; }
                  
                      IClientForm ParentForm { get; set; }
                      void Window\_Closed(object sender, WindowEventArgs args);
                  }
                  

                  // Below is the default method implementation

                  public static class IClientFormHelper
                  {
                      public static void SetUiContext(this IClientForm iClientForm, UIContextClass \_UiContext)
                      {
                          iClientForm.UIContext = \_UiContext;  // I put a breakpoint here and it's never hit
                          iClientForm.FormId = \_UiContext.AppContext.ClientGetUniqueFormId();
                          iClientForm.UIContext.AddForm(iClientForm);
                          iClientForm.OnClosed += iClientForm.UIContext.Window\_Closed;
                      }
                  }
                  

                  The main problem I see right now is that the default method code never runs. I assume the code is supposed to run as soon as I call the setter for UIContext that's declared in the main interface. Apparently, this is something I don't understand. What I want is for every IClientForm window to run the default code whenever the UIContext setter is called for that form, so that each separate window class doesn't need the same code repeated inside of it. Can someone spot what I've done wrong and point me in the right direction? I sincerely appreciate your time.

                  The difficult we do right away... ...the impossible takes slightly longer.

                  C Offline
                  C Offline
                  charles henington
                  wrote on last edited by
                  #11

                  I may not understand fully, but perhaps something like this?

                  public interface IMyInterface
                  {
                  static IMyInterface Instance = new MyStruct();
                  int Number { get; set; }
                  }
                  record struct MyStruct(int Number) : IMyInterface
                  {

                  }

                  Then you can use it like this

                  public void DoWork()
                  {
                  IMyInterface myInterface = IMyInterface.Instance;
                  myInterface.Number = 500;
                  Console.WriteLine(myInterface.Number);
                  }

                  1 Reply Last reply
                  0
                  • Richard Andrew x64R Richard Andrew x64

                    I'm having trouble getting my mind around how a default method in an interface works. Picture the below interface and default method implementation:

                    public interface IClientForm
                    {
                        delegate void WindowClosedDelegate(object sender, WindowEventArgs args);
                        event WindowClosedDelegate OnClosed;
                    
                        long FormId { get; set; }
                    
                        UIContextClass UIContext { get; set; }
                    
                        IClientForm ParentForm { get; set; }
                        void Window\_Closed(object sender, WindowEventArgs args);
                    }
                    

                    // Below is the default method implementation

                    public static class IClientFormHelper
                    {
                        public static void SetUiContext(this IClientForm iClientForm, UIContextClass \_UiContext)
                        {
                            iClientForm.UIContext = \_UiContext;  // I put a breakpoint here and it's never hit
                            iClientForm.FormId = \_UiContext.AppContext.ClientGetUniqueFormId();
                            iClientForm.UIContext.AddForm(iClientForm);
                            iClientForm.OnClosed += iClientForm.UIContext.Window\_Closed;
                        }
                    }
                    

                    The main problem I see right now is that the default method code never runs. I assume the code is supposed to run as soon as I call the setter for UIContext that's declared in the main interface. Apparently, this is something I don't understand. What I want is for every IClientForm window to run the default code whenever the UIContext setter is called for that form, so that each separate window class doesn't need the same code repeated inside of it. Can someone spot what I've done wrong and point me in the right direction? I sincerely appreciate your time.

                    The difficult we do right away... ...the impossible takes slightly longer.

                    R Offline
                    R Offline
                    RandyBuchholz
                    wrote on last edited by
                    #12

                    There different types of `interface` in C#. One is the `IInterface`, which is like the "interface is a contract" idea. ```cs class Foo : IBar{} ``` Another is the "Port Interface" ```cs class Foo { private int FooData1, FooData2; public interface Port { public const String Name = ""; public static ValueType Action(){ return (FooData1, FooData2); } } } ``` In the second case the `interface` is basically a lightweight static class (it even has constructors). Default implementations fall in between, sort of. Default implementations are like virtual methods. If you realize an `IInterface` that has default implementation and do not realize the operation, it will do something similar to the second case. But it places the method on the object and not on an inner interface. If the operation is realized it's like an auto-override of the default virtual implementation. Another difference is that the default implementation methods are instance and the `interface` methods are static.

                    C 1 Reply Last reply
                    0
                    • R RandyBuchholz

                      There different types of `interface` in C#. One is the `IInterface`, which is like the "interface is a contract" idea. ```cs class Foo : IBar{} ``` Another is the "Port Interface" ```cs class Foo { private int FooData1, FooData2; public interface Port { public const String Name = ""; public static ValueType Action(){ return (FooData1, FooData2); } } } ``` In the second case the `interface` is basically a lightweight static class (it even has constructors). Default implementations fall in between, sort of. Default implementations are like virtual methods. If you realize an `IInterface` that has default implementation and do not realize the operation, it will do something similar to the second case. But it places the method on the object and not on an inner interface. If the operation is realized it's like an auto-override of the default virtual implementation. Another difference is that the default implementation methods are instance and the `interface` methods are static.

                      C Offline
                      C Offline
                      charles henington
                      wrote on last edited by
                      #13

                      It may be worth pointing out that as the code stands Port interface has no access to FooData1 or FooData2.

                      public class Foo : Foo.Port
                      {
                      private Foo() { }
                      public int FooData1 { get; set; }
                      public int FooData2 { get; set; }
                      public interface Port
                      {
                      static Port Default = new Foo();
                      protected int FooData1 { get; }
                      protected int FooData2 { get; }
                      static (int, int) Action()
                      {
                      return (Default.FooData1, Default.FooData2);
                      }
                      }
                      }

                      Now we have access to FooData1 and FooData2. Foo is private and the only instance of Foo or Port is Foo.Port.Default and we can access it as such.

                      var bar = Foo.Port.Default;
                      var foobar = (Foo)bar;
                      foobar.FooData1 = 10;
                      foobar.FooData2 = 20;
                      Console.WriteLine(Foo.Port.Action());

                      If we want more than the single instance of Foo we need a Clone() method in Foo which can be easily done like this.

                      public object Clone()
                      {
                      var (X, Y) = Foo.Port.Action();
                      return new Foo()
                      {
                      FooData1 = X,
                      FooData2 = Y
                      };
                      }

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups