Replies: 66 comments 4 replies
-
Please! |
Beta Was this translation helpful? Give feedback.
-
@gafter, what about 'runtime constants for blittable structs'? That is, being able to declare a constant value for anything that has a constant bit layout (such as |
Beta Was this translation helpful? Give feedback.
-
Not sure if covered by #164 but I guess extending a type to implement an interface might benefit from CLR changes. |
Beta Was this translation helpful? Give feedback.
-
Well for starters I'll push #169 and #252, both suggestions around the inclusion of some form of thistype feature. Between them those issues have shown a significant interest in the feature, and I believe that would add a lot of power and niceness to the language. Along with shapes and a few other half formed ideas I should hurry up and post, I'd really like to see this as the Generics 2.0 update. |
Beta Was this translation helpful? Give feedback.
-
@TheOtherSamP Not that I know of, I was just quoting @gafter.
Indeed. I think the value of higher-kinds is so large that it does deserve one of those once in a decade major changes to the CLR (the last change of this size was to enable generics 1.0, I believe? although maybe the DLR was as significant). There are so many features that have been proposed that are skirting around this issue (concepts, shapes, default interface methods, etc.), it seems crazy to not do this properly. It's not even like it's a poorly understood concept. The constant mantra of "we can't touch the CLR" is understandable (to an extent), but has been frustrating when you see the language hit the limits of its apparently immutable runtime. So it's nice to see this question pop up. I'd love to see a more powerful constraints system also. |
Beta Was this translation helpful? Give feedback.
-
It is, though I'm not sure how much it really means given that it's basically a reposting of an old issue from 2015. Whether this is an indication that anything may happen in the near future isn't clear. While I'm in the habit of shamelessly promoting my own issues on here, I'd like to point out #255 where I asked about the status of the CLR. That received quite a bit of support, it's currently sitting at 15 thumbs, but this issue is the closest thing we've got to a response so far. |
Beta Was this translation helpful? Give feedback.
-
I would like to see more constrains like: -
I think every bullet have proposal but im writing it from phone so sorry for no exact information, will update late. Could it be possible to make static members as part of interface contract? Since you are planning on extending interface with default members and enable static methods with body it woould be unintuitive to be able write defalt static methods and instance members and make contract on instance members but no static members. For that there is no proposal, i can make one or post it in default member proposal Additionally i would like to mention my proposal that can introduce some form of intersection type based on already existing construct: dotnet/roslyn#7644 i think it may go well with higher-kind polymorphism? |
Beta Was this translation helpful? Give feedback.
-
What about:
|
Beta Was this translation helpful? Give feedback.
-
@gafter
|
Beta Was this translation helpful? Give feedback.
-
Support for I will absolutely relish the day when I can write an entire application and not ever worry about GC behavior because nearly everything I care about is stack allocated and/or shared via borrow semantics. 😁 |
Beta Was this translation helpful? Give feedback.
-
For me, the four most important would be:
|
Beta Was this translation helpful? Give feedback.
-
Also, with traits, we might need a new kind of constraints, for example, void F<T>() where X<T> : Trait Here, we constrained |
Beta Was this translation helpful? Give feedback.
-
As someone who has been using C# for game development scenarios for a long time, this is the thing that would be most beneficial to me. Fancy language features are nice, but this would be a game changer. I should also acknowledge that there's definitely been progress made already; Vector types, the Unsafe class, and ref returns were all very welcome. |
Beta Was this translation helpful? Give feedback.
-
@whoisj |
Beta Was this translation helpful? Give feedback.
-
I would second @whoisj regarding borrowing semantics. Did the CLR team have a look at the Rust language and its concept of ownership, borrowing and life times? https://www.toptal.com/software/eliminating-garbage-collector |
Beta Was this translation helpful? Give feedback.
-
'this' generic type constraint #169 |
Beta Was this translation helpful? Give feedback.
-
Another proposal related to generics #749 |
Beta Was this translation helpful? Give feedback.
-
Not a proposal from elsewhere, just an idea I've been thinking about. When you look at generator methods and In Python, none of this happens, because stack frames are Python objects, and the It shouldn't be that difficult to greatly simplify our coroutine operations by doing the same thing, but it would require three changes in the CLR:
If these were available, coroutines could be made much more performant by removing the state machine crud that clogs them up. |
Beta Was this translation helpful? Give feedback.
-
I think structs could be covariant with certain manner: using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
class Base { }
class Derived : Base { }
// Propssal: A struct all of whose fields are covariant could be covariant
struct CovariantStruct<T>
{
public T Value;
public IEnumerable<T> Items;
public (bool isValid, T value) Optional;
// Function members don't matter.
// `T` can be used on parameters.
public void Set(T value) => Value = value;
}
class Program
{
// Force to bitwise-copy with the Unsafe class.
static CovariantStruct<Base> BitwiseCopy(CovariantStruct<Derived> d) => Unsafe.As<CovariantStruct<Derived>, CovariantStruct<Base>>(ref d);
static void Main(string[] args)
{
CovariantStruct<Derived> d = new CovariantStruct<Derived>
{
Value = new Derived(),
Items = new List<Derived> { new Derived(), new Derived() },
Optional = (true, new Derived()),
};
// So far, conversion from CovariantStruct<Derived> to CovariantStruct<Base> requires unsafe context.
// However, this is safe as shown in the folloing.
CovariantStruct<Base> b = BitwiseCopy(d);
// All field accesses are safe (covariant).
Console.WriteLine(b.Value);
foreach (var item in b.Items) Console.WriteLine(item);
Console.WriteLine(b.Optional.value);
// This rewrite is safe because `b` is a copied value.
b.Set(new Base());
b.Items = new Derived[0];
b.Optional = (false, new Base());
// The original value `d` is not changed.
Console.WriteLine(d.Value);
foreach (var item in d.Items) Console.WriteLine(item);
Console.WriteLine(d.Optional.value);
}
}
// Open Question:
// How should "covariant struct" be defined
// 1. explicit or implicit?
// Version 1: This can be covariant.
struct X<T>
{
public T Value { get; set; }
}
interface I<out T>
{
// OK
X<T> GetX();
}
// ↓
// Version 2: This is no longer covariant.
struct X<T>
{
private StrongBox<T> _box;
public T Value { get => _box.Value; set => _box.Value = value; }
}
interface I<out T>
{
// NG. breaking change
X<T> GetX();
}
// Should the language introduce some modifier? such as `struct X<out T>` (similar to blittable types)
// 2. Syntax
// 2-1. `out` modifier on type parameters?
struct X<out T>
{
// This can be covariant because its field is covariant
public T _value;
// even though the type parameter `T` is used as parameters and set-accessors.
public T Value { get => _value; set => _value = value; }
public void SetValue(T value) => _value = value;
}
interface IVariant<out T, in U>
{
CovariantStruct<T> GetCovariantValue();
void SetContravariantValue(CovariantStruct<U> value);
}
// pros: Consistent with the modifier for interface/delegate.
// pros: No new keyword is needed.
// cons: It's not actually "out". Both "in" and "out" are allowed on function members.
// 2-2. `out` modifier on structs?
out struct X<T1, T2>
{
public T1 Item1;
public T2 Item2;
}
out struct Y<T1, T2>
{
// covariant with T1
public T1 Item1;
// but invariant with T2
public StrongBox<T2> Item2; // should be error. how?
}
// 2-3. other keywords?
struct X<covariant T1, T2>
{
public T1 Item1;
public StrongBox<T2> Item2;
}
struct X<variant T1, T2>
{
public T1 Item1;
public StrongBox<T2> Item2;
} |
Beta Was this translation helpful? Give feedback.
-
Seems too magic and opaque. Things that are semantically incompatible would be considered compatible. |
Beta Was this translation helpful? Give feedback.
-
Struct covariance proposed here is conceptually depth subtyping of record types, while interface covariance is behavioral subtyping. These are incompatible in terms of 'in'/'out', but, not so different in terms of subtyping. |
Beta Was this translation helpful? Give feedback.
-
Compare int value = 10;
ref int someRef = ref value;
ref? int otherRef = ref null;
if(ref someRef == ref otherRef) //Checking for same memory address
{
//Do Something
}
if(ref otherRef == null) //Checking for null ref.
{
//Do Something
} |
Beta Was this translation helpful? Give feedback.
-
@Neo-Ciber94, you can compare a You can either convert |
Beta Was this translation helpful? Give feedback.
-
From the recent announcement blog post:
DIM seems to be the only feature with runtime requirements in this release. Does that mean we only ship these features in major releases or also minor releases? |
Beta Was this translation helpful? Give feedback.
-
Please consider #2013 (Proposal: allow generic constraints to be part of the signature for overloading resolution) |
Beta Was this translation helpful? Give feedback.
-
I'd suggest simple types which map to C types for interop / p/invoke. We have some C code which uses As we need to support both 32 and 64 bit Linux, we currently have 80% of our p/invoke signatures, structs etc. duplicated with if/else code in wrapper classes. As far as I can see, those types need to be special cased in the runtime (like IntPtr), so I guess that might need a CLR extension... |
Beta Was this translation helpful? Give feedback.
-
Major or minor releases of what? I can easily imagine such changes would be introduced in a minor version of Visual Studio. But major runtime changes seem more likely in major releases of that runtime. |
Beta Was this translation helpful? Give feedback.
-
This solution would help me a lot I will give the most current example that I stumbled upon it public abstract class BasicBusiness<T, TKey> where T : class, new()
{
public async virtual Task<T> Get(TKey key) { /*...*/ }
public async virtual Task<T> Remove(TKey key) { /*...*/ }
/* etc */
}
public abstract class BasicBusiness<T> : BasicBusiness<T, int> where T : EntityIntKey, new()
{
}
public abstract class BasicBusiness<T> : BasicBusiness<T, short> where T : EntityShortKey, new()
{
}
public abstract class BasicBusiness<T> : BasicBusiness<T, Guid> where T : EntityGuidKey, new()
{
} This would have avoided me major refactoring efforts |
Beta Was this translation helpful? Give feedback.
-
Another use case (from #7902): public static T? GetFirst<T>(List<T> a) where T : struct => a.Count > 0 ? a[0] : null; // Member with the same signature is already declared
public static T? GetFirst<T>(List<T> a) where T : class => a.Count > 0 ? a[0] : null; // Member with the same signature is already declared The semantic nullable type (including both |
Beta Was this translation helpful? Give feedback.
-
This list would be amazing:
And, not sure if this is CLR or language, but generic parameters on operators. |
Beta Was this translation helpful? Give feedback.
-
If we were to plan for one language feature that requires a revision of the CLR, then we might as well do as many of them at the same time as make sense. What changes would we consider that would benefit from CLR support? This is a pared-down list for us to select from.
The most likely features we might do soon:
Other features that would benefit from CLR changes
Beta Was this translation helpful? Give feedback.
All reactions