I really loved the idea of default implementations on interfaces in C#8. But after trying it the disappointment was big...
So here's a simple example which I've found a part of the answer to in C#8 interfaces with properties/methods defined in them - apparently not working already why this is:
public interface IHasFirstNames
{
string? FirstName => FirstNames.FirstOrDefault();
List<string> FirstNames { get; }
}
public class Monster : IHasFirstNames
{
public List<string> FirstNames { get; } = new();
public Monster(params string[] firstNames)
{
FirstNames.AddRange(firstNames);
}
}
public static class Program
{
public static void Main()
{
var sally = new Monster("James", "Patrick");
var error = sally.FirstName; // Cannot resolve symbol FirstName
var works = ((IHasFirstNames)sally).FirstName;
}
}
But whats the point of having a default implementation of a property in an interface if you always have to cast it ugly?!
So according to the casting-solution of above I've tried this:
public interface IHasFirstNames
{
string? FirstName => FirstNames.FirstOrDefault();
List<string> FirstNames { get; }
}
public class Monster : IHasFirstNames
{
// Not ideal to declare the property here
// But at least the implementation is still in the interface
public string? FirstName => ((IHasFirstNames)this).FirstName;
public List<string> FirstNames { get; } = new();
public Monster(params string[] firstNames)
{
FirstNames.AddRange(firstNames);
}
}
public static class Program
{
public static void Main()
{
var sally = new Monster("James", "Patrick");
var error = sally.FirstName; // StackOverflow!
}
}
But against expectations this leads to a stack overflow as the cast to IHasFirstName
does not really call the default implementation of the interface.
Even when I implement a full getter with a dedicated variable of type IHasFirstName
it leads to a stack overflow.
The only ugly solution I've come up with is this with a dedicated getter method:
public interface IHasFirstNames
{
// Default implementation of a property is no use to me!
string? FirstName { get; }
// So I have to implement a getter method as default
public string? FirstNameGetter() => FirstNames.FirstOrDefault();
List<string> FirstNames { get; }
}
public class Monster : IHasFirstNames
{
public string? FirstName => ((IHasFirstNames)this).FirstNameGetter();
public List<string> FirstNames { get; } = new();
public Monster(params string[] firstNames)
{
FirstNames.AddRange(firstNames);
}
}
public static class Program
{
public static void Main()
{
var sally = new Monster("James", "Patrick");
var works= sally.FirstName;
}
}
It doesn't have to be a method. Apparently it's also OK if its a property with a different name. Once the property in the interface and in the class should have the same name it gets ugly.
Is there really no nicer solution for this?
thanks