Replies: 6 comments 6 replies
-
Can virtual statics be allowed in classes also? If yes, are there any plans to do it in future? |
Beta Was this translation helpful? Give feedback.
-
Nested types can see and override it. It's a common pattern to make abstract class constructors private to close the hierarchy. |
Beta Was this translation helpful? Give feedback.
-
I found this humorous. We've been working around the lack of either for 20 years! :) That said, I agree that static virtual satisfies 90% of the need anyway. Since async constructors seem to be dead; static virtual is more broadly useful. |
Beta Was this translation helpful? Give feedback.
-
Isn't that already allowed?
I just don't see a use case for virtual operators. Abstract factory methods will be an incredible feature, but operators are usually syntax sugar for instance methods and virtuality is achieved via the instance method: public interface IMagma<T> where T : IMagma<T>
{
public static T operator +(IMagma<T> lhs, T rhs) => lhs.Op(rhs);
protected abstract T Op(T other);
}
public record MyInt(int Value) : IMagma<MyInt>
{
MyInt IMagma<MyInt>.Op(MyInt other) => new (Value + other.Value);
} |
Beta Was this translation helpful? Give feedback.
-
Self type will be useful for many use cases of virtual static methods. Anyway, to be foreseeing, please discuss with BCL to design an "ultimate" replacement of current limited interfaces. We already have Do to the cost we have to implement and ship them in multiple versions, but please get a general design to avoid such duplication again. |
Beta Was this translation helpful? Give feedback.
-
I can think of a few cases where constraining instead of taking the interface directly makes sense:
public interface IOrderable {
abstract static int GetSomeMetadata();
int Order { get; }
}
class Foo : IOrderable { ... }
class Bar : IOrderable { ... }
public static IEnumerable<T> Order<T>(IEnumerable<T> values)
where T : IOrderable
=> values.OrderBy(x => x.Order);
var foos = new Foo[] { new(), new() };
var bars = new Bar[] { new(), new() };
var orderedFoos = Order(foos); // OK
var orderedBars = Order(bars); // OK
var orderedAny = Order(foos.Concat<IOrderable>(bars)); // does not compile! Before, adding an abstract member to an interface or class had known implications: you're breaking your descendants. Callers were mostly unaffected, if someone is calling After, adding an abstract static member can potentially source break any caller happening to fulfill a constraint with the constraint's type or a derived abstract type, even though it doesn't use the newly added member. Take the If that wasn't clear already, I think option 2 is a more sensible choice ;) |
Beta Was this translation helpful? Give feedback.
-
https://github.com/dotnet/csharplang/blob/master/meetings/2021/LDM-2021-02-08.md
Agenda
Beta Was this translation helpful? Give feedback.
All reactions