-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: support "type of the current object" as declared return type. #2494
Comments
Could you give an example of how this would be useful? Unless I am misunderstanding, don't constructors fill this role today? |
What would be other significant use of this syntax apart from method chaining? |
Maybe this one is giving more examples: |
@manish |
Duplicate of #155, I think. An equivalent of Scala's |
The idea is pretty simple, I guess. If you have a immutable base class A and a derived class B, and modifications are made through members in class A, those members always return A. If you want to apply the same modifications to type B without having to do a lot of casts, you need to overload any method within B. So, the method definition needs to say [type of this], i.e. return [A] when instance is typed [A] and [B] when instance is typed [B]. Two problems: First, if the method is only implemented in class A, it would need to be implemented type-agnostic to handle all thinkable derived types. It will quickly become a System.Activator.CreateInstance-party, with the compiler handling several variance issues. A performance nightmare coupled with unnecessary complexity. Second, this feature is already delivered through extensions and type-constraints. This spreads your code over two classes, which is problematic for some coding styles. Maybe, we should be capable of using static class members as extensions. |
@McZosch @gafter public class BaseClass
{
public virtual this Foo()
{
return this;
}
}
public class DerivedClass1 : BaseClass
{
public override this Foo()
{
return this;
}
}
public class DerivedClass2 : BaseClass
{
public override this Foo()
{
// Is a valid call, because the "this" reference is returned.
return base.Foo();
}
} Co-variant return types have different semantic. class Compilation ...
{
virtual Compilation WithOptions(Options options)
{
// the proposal is not allowing new object creation.
return new Compilation();
}
} class CSharpCompilation1 : Compilation
{
override CSharpCompilation1 WithOptions(Options options)
{
// the proposal is expecting CSharpCompilation as return type.
return new CSharpCompilation1();
}
} class CSharpCompilation2 : CSharpCompilation1
{
override CSharpCompilation1 WithOptions(Options options)
{
// the proposal is expecting CSharpCompilation2 as return type.
return base.WithOptions(options);
}
} |
Well... after some times I think we could just workaround with generic extension method public class OurStringBuilder
{
internal void Append();
}
public class OurStringBuilderExt
{
public S Put<S>(this S sb,string s) where S : OurStringBuilder
{
sb.Append(s);
return sb;
}
public S AppendLine<S>(this S sb,string s) where S : OurStringBuilder
{
sb.Append(s);
sb.Append(Environment.NewLine);
return sb;
}
}
new OurStringBuilder().Put("s").Put("t").Put("r").Put("i").Put("n").AppendLine("g"); This is satisfied our need. It also work with interface on struct and everything. Also we could implement most logic in extension method instead of its base class |
What about returning a variable types? Note this is not the way I would do it but its just a example..
Returning this only works if the method is in the current class |
@Shadowblitz16 |
The text was updated successfully, but these errors were encountered: