-
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
readonly generic constraint #3691
Comments
why is returning default from a method a "hole" in |
because we allocate stack space and initialize on the stack for the supposed given already allocated value. |
... would you care to elaborate? That still doesn't make sense. |
What does't that we do something we should not? |
I can see an argument for allowing: public interface IS { void Foo(); }
public readonly struct S { public void Foo() { } }
public void M<T>(in T s) where T : readonly, IS
{
s.Foo(); // Doesn't make a defensive copy of 's'
} However:
In fact, I'm having a very hard time trying to understand what's being proposed. Let me walk through my confusion:
OK, so we've got a generic method with a
Is this meant to parse as "and the param is (not passed by in) or (declared readonly)" or should it be "and the param is not ((passed by in) or (declared readonly))"? Params can't be "declared readonly" anyway, so I'm going to ignore that bit for now and read it as "and the param is not passed by in". OK, so we're looking at a method like: public T M<T>(T t) where T : struct, readonly
{
return default;
}
Wait, what?
What does "the result should be null otherwise the in value" mean? What determines whether |
I am good with #3055 doing what it does there, here is different. Do not 0 init the stack, it should be initialed already for the struct already by the caller. no return other that t should be made due to the |
What does C# already has |
Where does one read about the semantics of |
A |
I know about readonly
public readonly int M() {
return 1;
} This is not valid... |
So are you saying that public static T M<T>(in T t) where T : readonly { return default; }
var m = M<int>(5);
Console.WriteLine(m); ...would actually print |
From what I understand you're saying you don't want the |
I linked the spec proposal -- that's the best we have. We only have an ECMA spec for C# 5. The "Motivation" section lays it out. This doc talks about it a bit as well.
For example: public class C
{
public void Test()
{
S original = new S();
M(in original);
}
public void M(in S s)
{
s.NonReadonly();
}
}
public struct S
{
public void NonReadonly() { }
} The compiler inserts a hidden copy of If you give the struct a public class C
{
public void Test()
{
S original = new S();
M(in original);
}
public void M(in S s)
{
s.Readonly();
}
}
public struct S
{
public readonly void Readonly() { }
} There's no hidden copy of A As you can see, none of this is to do with returning values from a method, it's all about whether or not a defensive copy of a struct is made before calling one of its methods. This is why I'm confused by your focus on return values. |
Follow-up: is it possible that during inlining the JIT elides this? I don't know, but I think it could. |
Ewww this is on structs only? why? |
... because you can have You're the one talking about |
You miss the point, I have a struct I pass by in, i get that in from a ref.. |
Then why did you say
? |
Because why, any method should be able to designate |
The |
What do you mean by "on return"? |
I like readonly structs. You could return |
Perhaps it should in some cases where I return the |
Ah, so you want something like this: public readonly ref T M<T>(in T v) where T : struct {
return ref v;
} |
I'm trying to get you to explain how you think |
I could palette that. |
Nod, this interrogation/negotiation style of "proposal" is exhausting. |
I considered |
Is this kinda what you want? public static in T M<T>(in T t) where T : struct { return t; } Where the return value must be an |
Yes and what @HaloFour also showed are kinda of in the same dimension I think AFG |
I can add them it just makes it harder or worse imho |
It can't be more confusing than what you have already 😈 Is it correct that you want to be able to write something like this: public ref T M<T>(ref T v) where T : struct {
return ref v;
} But where the parameter is |
What's AFG? I haven't heard that one before. Sorry if I'm just illiterate with internet speak |
I like that example public ref T M<T>(ref T v) where T : struct {
return ref v;
} and will say yes but I really like @mikernet example also public static in T M<T>(in T t) where T : struct { return t; } Although I would prefer to read it as public static readonly T M<T>(in T t) where T : struct { return t; } |
At first glance, sorry |
The problem here is that you're returning a pointer to a struct, but This method is a public ref T M<T>(ref T v) where T : struct {
return ref v;
} This is legal today, if you hadn't realised. |
Initially the syntax for |
Sure, |
That;s why I like @mikernet's example.
|
I would recommend updating your OP, and clarifying that you want to be able to return a reference to a struct from a method, and allow that reference to be one that was passed into the method using Make sure you also include motivating examples -- sure you could do this, but why would you want to, for instance. |
Will do asap, ty for your assistance and critique |
To be clear, that's already possible: https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQMwAJboMLIN7LpHqHFroBOApgGaVUCGwA9gHYA2AnugCroCyAHh4A+ABQBLVr3QA3AJToA7gAsq1GSHQBnAC4UArgGNd6AkmKXMAdnp1ZAblJEAvshdA== @juliusfriedman we appreciate the enthusiasm. But your proposals need more work. You need to understand the spec and propose actual changes that don't conflict with the existing language. Afaict, this has been 30+ messages to understand that you are trying to propose something that already exists. |
D'oh, didn't realize it was |
🤣 Haha, whoooops. |
I agree with Fred here. And this ties into the conversation you and I were having yesterday on emphasizing clarity and providing more context and information to assist with the discussion. Being vague and responding cryptically does not help your proposals out. Given taht this appears to be a proposal for something that already exists, I'm goign to close this out. You are more than welcome to continue making proposals here. My only request is that you invest a little more time into them to help save a lot of people spending many hours trying to unpack exactly what it is you are referring to. Thanks much! |
No prob so long as you do the diligence you promised and we reopen when appropriate and if warranted. otherwise i find this very faux paus` |
Why would this be reopened? The exact feature you are proposing already exists, the syntax for it is above. |
I said when and if... |
Consider
Something which is not allowed
Another thing that is allowed but has a hole IMHO
Specifically
Uninteresting code
I propose that the
readonly
generic constrain be created such that if the type is notreadonly
or passed byin
that the compiler should throw a warning CSXXX otherwise should compile as allowed.The spec should be modified if required such that if a method in which
return default
is used in the aforementioned scenario and the param is not passed byin
or declaredreadonly
then the result should benull
otherwise thein
value and not anothernew default
valueMotivation memory protection semantics can be built around this inter alia
To be combined with the other proposed or existing constrains such as but not limited to
struct
orinterface
Possibly make
readonly
available as a method keyword everywhere.The text was updated successfully, but these errors were encountered: