Provide a way to opt-out of structural typing. #5278
Replies: 7 comments 16 replies
-
I get where you're coming from here, but what actual problem does this cause? What dangers are there and, if any, how likely are they to actually occur? |
Beta Was this translation helpful? Give feedback.
-
It could be better if those features are marked by interface instead of structural typing from the start. I think an attribute with scope of member/type/module can be used for marking that without introducing large overhead. |
Beta Was this translation helpful? Give feedback.
-
Structural typing is always a workaround of lacking of type trait (shape). It's necessary to remove structural typing after adding shape to C#. |
Beta Was this translation helpful? Give feedback.
-
We could give hints with attributes at type level. In the example of |
Beta Was this translation helpful? Give feedback.
-
Perhaps a [CountProperty(nameof(Count))]
public struct Vector2<T>
{
public T X { get; }
public T Y { get; }
public T Length => throw new NotImplementedException("Calculate the Magnitude");
public T Count => 2;
} Edit: Possibly also be able to opt-out: [CountProperty(OptOut = true)]
public struct Vector2<T>
{
public T X { get; }
public T Y { get; }
public T Length => throw new NotImplementedException("Calculate the Magnitude");
} |
Beta Was this translation helpful? Give feedback.
-
Whenever roles/extensions come in, to handle this scenario we would need some way for a type to mark itself as excluded from specific roles, should they happen to meet the structure, like: // Assume the following role
role RCountable
{
public int Count { get; }
}
public struct Vector2<T>
neglect RCountable
{
public T X { get; }
public T Y { get; }
public int Count => 2;
} |
Beta Was this translation helpful? Give feedback.
-
This would be useful with |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Issue
Today there exist many cases where the language will allow some feature or functionality based on structural typing. Some examples are:
foreach
where the type implements aGetEnumerator
extensionDispose
on ref structs if aDispose
method existsthis[int index]
andint Count { get; }
orint Length { get; }
properties existGive the diversity across the entire ecosystem and the possibility for domain specific terminology, this means there may be cases where a member exposed may conflict with the language assumptions about a given "shape".
Example
One such example is that in the space of numerics and
euclidean vectors
a common term is "length". This is sometimes also referred to asmagnitude
ornorm
, butlength
remains the most common domain terminology. Being vectors ofn
dimensions, they are also frequently indexable and thus, an integer based euclidean vector may be applicable forindexing
orlist
patterns, despite the exposedLength
being the wrong term and thus leading to potential bugs or issues.There can be various other considerations here as well, such as
Length
being preferenced overCount
when the user, for various reasons, may want the inverse.Proposed Solution
There should be a way to opt-out a member or set of members from participating in structual based typing. One can imagine multiple scenarios for this ranging from a single big switch saying a type or member doesn't participate in any structural typing to more fine grained switches that indicate the type or member does not participate in a given scenario of structural typing (e.g.
Length
doesn't represent the language concept of "collection length").With such a switch or set of switches, the compiler could also produce a more explicit error message indicating the type has been opted out of the given pattern.
Beta Was this translation helpful? Give feedback.
All reactions