-
Imported from https://github.com/dotnet/roslyn/issues/15983. Please see that issue for discussion. Currently to use
I propose that the exact same syntax as class GenericClass<T>
{
public string X { get; }
}
class GenericClass<T1, T2>
{
public string Y { get; }
} These expressions are currently valid, and would stay valid: nameof(GenericClass<int>)
nameof(GenericClass<int>.X)
nameof(GenericClass<int, byte>)
nameof(GenericClass<int, byte>.Y) These expressions would become valid, and would have the same respective results: nameof(GenericClass<>)
nameof(GenericClass<>.X)
nameof(GenericClass<,>)
nameof(GenericClass<,>.Y) Using the terminology in https://github.com/ljw1004/csharpspec, it may be that all we need to do in grammar terms is to expand |
Beta Was this translation helpful? Give feedback.
Replies: 28 comments 9 replies
-
IIRC the limitations of syntax with Now that |
Beta Was this translation helpful? Give feedback.
-
Checkout the previous discussion on roslyn repo. The parser is already capable of skipping missing types in a type argument list, the language grammar, however, should be updated to allow this. |
Beta Was this translation helpful? Give feedback.
-
Sounds like little reason to not do this, then. But even if the parser couldn't handle this today I'm certainly not arguing that it shouldn't be modified to support it. I was always disappointed in the limitations imposed on |
Beta Was this translation helpful? Give feedback.
-
To be clear,
All this would produce the string |
Beta Was this translation helpful? Give feedback.
-
All three of those are invalid with |
Beta Was this translation helpful? Give feedback.
-
Why? Do you expect different overloads of If all those yield the same result, why having them at all? Wouldn't |
Beta Was this translation helpful? Give feedback.
-
@paulomorgado I believe you didn't read my comment in its entirety. |
Beta Was this translation helpful? Give feedback.
-
Almost, @alrz. Only missed one or two words. 😄 |
Beta Was this translation helpful? Give feedback.
-
No, but I expect the IDE to be able to know when to update Say you have two methods called |
Beta Was this translation helpful? Give feedback.
-
But if that is ever allow on void M1() { ... }
int M1(int I) { ... }
void M2(Action a) { ... }
void M2(F<int, int> f) { ... }
M2(M1());
M2(M1(int)); |
Beta Was this translation helpful? Give feedback.
-
@paulomorgado Let's start simple, but yes I agree. For now all I want is to be able to start using open generic types. That's by far the most common and important use case and I don't want anything to postpone that. |
Beta Was this translation helpful? Give feedback.
-
It is still legal to name a method |
Beta Was this translation helpful? Give feedback.
-
One issue I remember us dodging with the current restrictions is when you "double dot": class C<T> where T : D
{
public T P { get; }
}
nameof(C<>.P.X) // Allowed for which names X? While it is clear that all
If we were to go down this route, I'd be in favor of 3. 1 gets complicated (what if |
Beta Was this translation helpful? Give feedback.
-
Language design meeting November 6th:
(https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-11-06.md#roslyn-20450) If the community addressed the "expensive to implement" part and we went with Mads' option three above, preventing the semantic dark corners, why would you say no? (I agree with Mads' choice. Double dotting is vanishingly rare; no one will miss it with open generics. The rule unblocks a desirable use case, desirable both for very practical reasons and for ideological satisfaction.) @alrz has already implemented dotnet/roslyn#20450. |
Beta Was this translation helpful? Give feedback.
-
Since I don't see an answer at first glance, what is the expected result of, e.g. |
Beta Was this translation helpful? Give feedback.
-
@Joe4evr : As per the original comment, the result of |
Beta Was this translation helpful? Give feedback.
-
The current implementation has already some semantic (dotnet/roslyn#20600) and syntactic (#911) dark corners. You can just add open types to that list as another corner. BTW dotnet/roslyn#20450 already handled that case. See NameOfTests.cs#L1355 |
Beta Was this translation helpful? Give feedback.
-
@jskeet Ah. Yeah, that wouldn't have worked for my usecase (I needed it to be "List`1"). |
Beta Was this translation helpful? Give feedback.
-
I would think that if you have any For example, I should be able to do However if there is a constraint, then you could in theory traverse the constraint. i.e. given: interface IFoo
{
string Name { get; }
}
class Bar<T> where T : IFoo
{
T Baz { get; }
} I should be able to do Looking briefly at the tests @alrz posted above, this seems to be the approach taken in that pr. |
Beta Was this translation helpful? Give feedback.
-
Does the PR include proposed name lookup rule specification changes to justify the behavior? |
Beta Was this translation helpful? Give feedback.
-
No, there was no specification to follow at the time and the PR was closed pending LDM decision. |
Beta Was this translation helpful? Give feedback.
-
If a class has a recursive generic constraint, you must write a dummy implementation of the class in order to use throw new InvalidOperationException($"... {nameof(AggregateRoot<ThisShouldNotBeNecessary>)} ...");
private sealed class ThisShouldNotBeNecessary : AggregateRoot<ThisShouldNotBeNecessary>
{
public override ThisShouldNotBeNecessary Clone()
{
throw new NotImplementedException("This should not be necessary.");
}
} public abstract class AggregateRoot<TThis> where TThis : AggregateRoot<TThis>
{
public Id<TThis> Id { get; }
public abstract TThis Clone();
}
public readonly struct Id<TRoot> where TRoot : AggregateRoot<TRoot>
{
public int Value { get; }
} It's a parody of the fact that it's meaningless to specify generic type arguments anyway. |
Beta Was this translation helpful? Give feedback.
-
@gafter any chance the LDM could revisit this? Considering that there are two PRs for implementation (dotnet/roslyn#4907, dotnet/roslyn#20450), it doesn't seem like it's as expensive to implement as the LDM originally suggested. |
Beta Was this translation helpful? Give feedback.
-
@yaakov-h Since the language spec doesn't have rules for looking up members in open types, we do not yet have a good spec for the meaning of the proposed construct. |
Beta Was this translation helpful? Give feedback.
-
Any progress on this issue? |
Beta Was this translation helpful? Give feedback.
-
Can this proposal can be revived? |
Beta Was this translation helpful? Give feedback.
-
I currently require accessing some My current workaround is to create a static class with I am very hopeful that this will be merged soon. It is not very fun to deal with. |
Beta Was this translation helpful? Give feedback.
-
Championed proposal being scheduled for LDM soon: #8480 |
Beta Was this translation helpful? Give feedback.
Championed proposal being scheduled for LDM soon: #8480