3

I recently discovered (thanks to a broken build targeting core 2.2) that this is now legal in C# 8

public interface ISimple
{
    public string Simon { get; }
}

ISimple is an interface, Simon has no implementation, but the public keyword is allowed.
I understand that public is there for Default Implementations in Interfaces but this property has no implementation.

Compared to this, which is definitely to be expected

public interface ISimple
{
    public string Simon => "met a pie man";
}

I doubt this is an oversight; if it's not, what is the rationale for having this? What use could it be?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Binary Worrier
  • 50,774
  • 20
  • 136
  • 184
  • 1
    Why *shouldn't* it be allowed? `public` is the default access modifier, it could be `private`, `protected` or `abstract`. A `protected abstract string Simon {get;}` would specify a member that any implementing class has to provide but the *users* can't access. DIMs defined on the interface though, can use it – Panagiotis Kanavos Oct 09 '19 at 13:07
  • I suppose when you look it like that . . . however, I went straight to looking for a deeper meaning. – Binary Worrier Oct 09 '19 at 13:12
  • 1
    That's the deeper meaning. You can specify members that *can't* be used by clients, that can only be used by DIMs or should only be available to the class. In both DIM scenarios, interface versioning *and* traits, `protected` etc are desirable - a trait can add properties and methods that are only meant for the class. – Panagiotis Kanavos Oct 09 '19 at 13:14
  • 1
    As for the deeper-deeper-deeper meaning, it seems that Xamarin/Android interop is indeed the reason for DIMs. Java and Android do use DIMs. If you consider that an Android app has to work across dozens of Android API Levels, DIMs *on the SDK's side* make perfect sense. A Xamarin application would **really** benefit if it could use or override those implementations directly – Panagiotis Kanavos Oct 09 '19 at 13:16
  • @PanagiotisKanavos Fancy posting an answer? – Binary Worrier Oct 09 '19 at 13:38
  • Just did - the question gave me some extra ideas and I started searching for *Android* uses of DIMs. I think I found a good one and I suspect we'll start seeing DIMs in the Azure SDK too – Panagiotis Kanavos Oct 09 '19 at 13:50

1 Answers1

3

The deeper-deeper-deeper meaning is that the real motivation behind DIMs is Xamarin/Android interop.

Android and Java use DIMs for interface versioning. An Android app has to work across dozens of Android SDK levels and DIMs are used to provide default implementations to apps that were built for older versions of the SDK. A Xamarin application would really benefit if it could use or override those implementations directly.

For example the LifeCycleObserver interface is used to notify applications for specific lifecycle events. Applications can implement this to get notified of events. The DefaultLifeCycleObserver interface uses empty default methods to provide a default implementation, so applications don't have to handle all states. New states could be added and applications wouldn't have to change at all:

/**
 * Callback interface for listening to {@link LifecycleOwner} state changes.
 * <p>
 * If you use Java 8 language, <b>always</b> prefer it over annotations.
 */
@SuppressWarnings("unused")
public interface DefaultLifecycleObserver extends FullLifecycleObserver {
    /**
     * Notifies that {@code ON_CREATE} event occurred.
     * <p>
     * This method will be called after the {@link LifecycleOwner}'s {@code onCreate}
     * method returns.
     *
     * @param owner the component, whose state was changed
     */
    @Override
    default void onCreate(@NonNull LifecycleOwner owner) {
    }

The Android-DisposeBag overrides this default implementation to dispose ReactiveJava streams only when the application pauses or shuts down :

class DisposeBag @JvmOverloads constructor(owner: LifecycleOwner,
                                           private val event: Lifecycle.Event = DisposeBagPlugins.defaultLifecycleDisposeEvent)
    : Disposable, DisposableContainer, DefaultLifecycleObserver {

...

    override fun onPause(owner: LifecycleOwner) {
        if (event == Lifecycle.Event.ON_PAUSE) dispose()
    }

    override fun onStop(owner: LifecycleOwner) {
        if (event == Lifecycle.Event.ON_STOP) dispose()
    }

    override fun onDestroy(owner: LifecycleOwner) {
        if (event == Lifecycle.Event.ON_DESTROY) dispose()
    }

I wouldn't be surprised if the Azure SDK started using DIMs. That would explain why Scott Hunter kept talking about modern cloud environments while describing DIMs during the .NET Conf keynote.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236