Replies: 151 comments
-
Beta Was this translation helpful? Give feedback.
-
I'm wondering if we can borrow It works by saying "this method or property returns a type of the current instance". For example:
In this instance, Of course, Objective-C has a much more dynamic runtime than .NET does, so the following would have to be invalid in C#:
In this instance, |
Beta Was this translation helpful? Give feedback.
-
Also possibly related is the override return type covariance proposal? |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h I can't understand how we can work with instancetype. How we should create new instancetype and how we should use returned instatcetype. |
Beta Was this translation helpful? Give feedback.
-
Perhaps you might want to consider making the protected variables "internal protected". |
Beta Was this translation helpful? Give feedback.
-
I don't understand. Why don't you just do this.
I mean having one interface for your fluent API. If you change class all your class need to implement the same method. So why don't you just make a common interface you return each time. |
Beta Was this translation helpful? Give feedback.
-
@GeraudFabien how you can add GetD() if IMain is third party library? interface IDerived : IMain
{
IDerived GetD();
} |
Beta Was this translation helpful? Give feedback.
-
Well you can, but then Another example is |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h IClonable is not another example, because in method Clone() we must to create new instance. We can't create new instance of this. We can't know in advance constructor of deriverd class. We can change this instance and return this. |
Beta Was this translation helpful? Give feedback.
-
@VanKrock |
Beta Was this translation helpful? Give feedback.
-
@jnm2 It's another logic, it's not this, may be "instancetype" or else. Instancetype cannot be created in current class, must be abstract and must be overrided in each derived class. But "this" - "can work like void, but return this"; |
Beta Was this translation helpful? Give feedback.
-
@VanKrock That's just syntactic sugar for the method declaration. What does the method signature look like? How would this work on a CLR level? How does it work with inheritance? |
Beta Was this translation helpful? Give feedback.
-
public interface IMyClass
{
this SomeChange();
}
public class MyClass : IMyClass
{
public this SomeChange()
{
}
}
public class Test
{
public void Start(IMyClass myClass)
{
myClass.SomeChange().SomeChange();
}
} Equals public interface IMyClass
{
void SomeChange();
}
public class MyClass : IMyClass
{
public void SomeChange()
{
}
}
public class Test
{
public void Start(IMyClass myClass)
{
myClass.SomeChange();
myClass.SomeChange();
}
} It's syntax sugar |
Beta Was this translation helpful? Give feedback.
-
AlternativesAlternative 1public class B
{
public virtual B M() => this;
}
public class C : B
{
public override B M() => this;
}
public static class D
{
public static C M(this C c) => (C)c.M();
} Problem: a cast is necessary at every call. Alternative 2public class B<T> where T : B<T>
{
public virtual T M() => (T)this;
}
public class Z<T> : B<T> where T : B<T> { }
public class C : Z<C>
{
public override C M() => this;
}
public static class D
{
public static C M(this C c) => c.M();
} Problem: it is not possible to have non generic intermediary classes inheriting B (like non generic Z). I think this would be a great feature! BonusThis could also work for extensions methods: public static this M(this C c) { } |
Beta Was this translation helpful? Give feedback.
-
@Logerfo We can't call extension method M because we have non extension method M with identical signature. But for extensions you can use: public static T M<T>(this T c) where T : C { return (T)c.SomeMethodReturnC(); } |
Beta Was this translation helpful? Give feedback.
-
Okay well then there is nothing more for me to discuss here. You can say things like "withers" and "constructing message types" and "immutable builders" all you want but the problem I can see clearly in my mind with how to actually implement them using what is being proposed here is impossible for me to demonstrate without you actually showing an example of how it would be implemented in C# with this feature that can be dissected. I wish you the best of luck in getting your feature adopted. Enjoy the rest of your weekend. |
Beta Was this translation helpful? Give feedback.
-
Perhaps you should take your concerns then to the respective proposals? |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi Which respective proposal? If the matter of having |
Beta Was this translation helpful? Give feedback.
-
@mikernet There are a bunch out there. Maybe try looking for builders/immutable-objects/withers/records/etc. You could even look at the ones about covariant return types. Though i don't particularly expect any individual proposal to be done, it will be more likely that several will be bucketed into a full feature/pillar for a future release that are all about the general theme. |
Beta Was this translation helpful? Give feedback.
-
While i can't say for certain, this does feel like an area that the LDM may be very interested in lookin at once NRT is done. Open question though if they'll eventually go here, or if they'll go in other big-pillar areas (like 'shapes'). But there's been enough interested in the pieces (and the whole) here over the year to give me a strong belief that something like this could have a reasonable chance of happening in the next 1-2 releases. |
Beta Was this translation helpful? Give feedback.
-
I've been mostly keeping up with those proposals and after some initial searching I can't seem to find anything that would cause me concern on those proposals so if you or anyone else comes across where this topic is being discussed on a proposal somewhere else and posts a link to it here so the discussions can be cross-referenced that would be lovely. |
Beta Was this translation helpful? Give feedback.
-
i believe in all the immutability proposals you'll be getting new instances. But, for the case of records/withers, you'd want the resultant type to be your containing type. |
Beta Was this translation helpful? Give feedback.
-
I just thought of another use case for a Specifically: public delegate EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);
public class Control {
public event EventHandler<this, MouseEventArgs> MouseDown;
//instead of:
public event EventHandler<Control, MouseEventArgs> MouseDown;
}
public class Button : Control {
}
public class SomeWindow {
private Button someButton;
public void Run() {
someButton.MouseDown += (s, e) => { }; // s is of type Button, not Control
}
} |
Beta Was this translation helpful? Give feedback.
-
What would the code gen be Note this is already sort of possible with the following pattern: public class Control<T> where T : Control<T>
{
public event EventHandler<T, MouseEventArgs> MouseDown;
}
public class Button : Control<Button> {
}
public class SomeWindow {
private Button someButton;
public void Run() {
someButton.MouseDown += (s, e) => { }; // s is of type Button, not Control
}
} |
Beta Was this translation helpful? Give feedback.
-
That pattern is not generally applicable to deeper hierarchies, which are particularly common with controls. You can do the same thing for getting a Not sure about codegen. I presume similar to whatever solution is created for a |
Beta Was this translation helpful? Give feedback.
-
Also that pattern doesn't really work here (or in many other scenarios as well) because now there's no way to treat Control control = GetControl(criteria);
control.MouseDown += OnControlMouseDown; //fails because no way to define the event on non-generic Control class |
Beta Was this translation helpful? Give feedback.
-
I found solution of my problem. We can use implicit interface implementation and extension methods. public interface IMyClass
{
void SomeChange();
}
public static class Extensions
{
public static T SomeChange<T>(this T obj) where T : IMyClass
{
obj.SomeChange();
return obj;
}
}
public class MyClass : IMyClass
{
void IMyClass.SomeChange()
{
Console.WriteLine("Some change");
}
}
//We can override this method in derived class
public class Derived : MyClass, IMyClass
{
void IMyClass.SomeChange()
{
Console.WriteLine("Derived change");
}
} |
Beta Was this translation helpful? Give feedback.
-
Didn't you already present that solution in the first post of this issue? |
Beta Was this translation helpful? Give feedback.
-
No. Examples in first post have a problems. Current solution resolve that problems. We can use private fields of |
Beta Was this translation helpful? Give feedback.
-
Oh I see what you mean. I do something similar - an extension method calls an internal virtual method on the class which can be overridden by derived classes, so interfaces arent really needed to make this work. The extension method can make discoverability a problem at times though and it's somewhat annoying to not have everything encapsulated, but it's definitely the best type of solution to this right now and it works fairly well. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Now we can't create true fluent api with inharitance and interfaces
We can use generics:
But we have a problems with inheritance of interface and Implicit casts.
We can use extensions:
But we can't use protected properties.
I see useful return this:
It's can work like void, but return this
Beta Was this translation helpful? Give feedback.
All reactions