Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Unity C# 8 support

Discussion in 'Experimental Scripting Previews' started by JesOb, Apr 18, 2019.

  1. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    TNT is also a tool. A tool that you could use to bomb the hole in the rock to mine something or just digging a deep hole in the ground. It is totally useful. But that's not something you would want into your typical toolbox. It has tendency to be dangerous and might destroy everything. Even just its existence is scary that it might leak nitroglycerine out. Even you don't use it but other people that use the same toolbox as you might use it carelessly without you knowing

    DIM is like that. I don't want it lurking around so no one can misuse it. Like a gun policy
     
  2. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Still doable with generic extension method. And better yet, generic extension method can pass `this` by reference so it can be mutate for struct creation too
     
  3. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    And why is that ?
     
  4. AliAlbarrak

    AliAlbarrak

    Joined:
    Jan 24, 2018
    Posts:
    15
    I think people just misunderstood the main goal behind default interface implementation and started using it as a design tool.
    You can clearly see in the motivation section of DIM documentation that is was made to help API authors add more functionality without breaking compatibility. Traits in the other hand came as a side effect of DIM.

    Use cases mentioned above can all be solved using a parent abstract class or using generic extension method. In fact, DIM was called virtual extension methods in the same document linked above.
     
    Qbit86 and slimshader like this.
  5. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    If everyone write their own code and never use other people code. Or every person in the world always use everything correctly, we wouldn't need to worry and can trust the good motivation
    Same as second amendment of USA that people can armed themselves to protected from tyranny state, that was motivation. But people use that amendment to carry machine gun to public place and shoot on innocents people like at school

    Unlike other feature in C#. DIM can be silently insert itself into new version of the code unknowingly to the user. It can break things with the feature itself, not just the wrong logic and coding. There could be breaking change with diamond inheritance

    Actually we have heated and controversial debate on DIM topic for years since it first try to come into existence. But all the hellish downside has never been telling publicly because Microsoft people want to promote their new feature. They hide all the problem about DIM from you all. This is typically politics and marketing scheme
     
  6. Jorhoto

    Jorhoto

    Joined:
    May 7, 2019
    Posts:
    99
    Just use DIM correctly, as any other feature. I prefer to have the choice. It is like C++ multiple inheritance, it is very powerfull and dangerous at the same time, but, I prefer it to be there.
     
  7. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    DIM is quite useful many times I got situations when I had methods that operates on the same interface that just begged for this feature.

    Also you can make static DIM that lets you get rid of most ugly utility kind of modules.

    For example if Vector3 was an interface you could have such a construct.
    IVector3 IVector3.Cross(IVector3 a,IVector3 b)
     
  8. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    DIM would largely be useless there because default implementations always cause boxing on value types (even if you call them through a constrained generic parameter), which would be unacceptable for this method.
     
    Thaina and JesOb like this.
  9. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    OK example is a little unlucky.
    But you should generally not use interface on structure anyway.
     
  10. WeirdBeardDev

    WeirdBeardDev

    Joined:
    Feb 16, 2013
    Posts:
    14
    Or you could use an abstract class between the interface and the rest of the concrete classes. I believe Microsoft uses this heavily in the .NET libraries.
     
  11. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Apologize that I would repeat again and again that almost all of your example, can bet it 95% of the times, would be solve with just generic extension method with equally the same or even better

    Only 5% of the times that you really really need to implement DIM and extension method cannot do the trick at all, which is virtual extension method. This might really require DIM. But in my opinion that's not worth the cost of having DIM in the language

    As for your vector operation, like that cross product, please let me reframe it into extension method

    Code (CSharp):
    1. public interface IVector3
    2. {
    3.     ref float X { get; }
    4.     ref float Y { get; }
    5.     ref float Z { get; }
    6. }
    7.  
    8. public static class Vector3Ext
    9. {
    10.     public float Dot<T>(in this T l,in T r) where T : struct,IVector3
    11.     {
    12.         return (l.X * r.X) * (l.Y * r.Y) * (l.Z * r.Z);
    13.     }
    14.  
    15.     public T Cross<T>(in this T l,in T r) where T : struct,IVector3
    16.     {
    17.         T v;
    18.         v.X = (l.Y * r.Z) - (l.Z * r.Y);
    19.         v.Y = (l.X * r.Z) - (l.Z * r.X);
    20.         v.Z = (l.X * r.Y) - (l.Y * r.X);
    21.         return v;
    22.     }
    23. }
    24.  
    25. public struct MyVec : IVector3
    26. {
    27.     public float X,Y,Z;
    28. }
    29.  
    30. ////
    31.  
    32. var v0 = new MyVec();
    33. var v1 = new MyVec();
    34.  
    35. var cross v0.Cross(v1); // no boxing or even copy because generic extension method
    36.  
    37. ////
    And so please forget about DIM
     
  12. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Seriously, this is the example of people start misusing DIM even it does not exist in unity yet. This is the reason I would appreciate that unity would not implement DIM in their system for eternity
     
  13. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    There are also people that don't like extension methods:
    - they give false impression that they are part of an object
    - you can invoke them on null objects (bug/feature ?)
    should we remove them and go back to good old utilities ?

    DIM != extension method - different things for different jobs.
    (Also your realization of IVector3 with extension methods is unacceptable for me. Why should I inflate and divide my code when I can have pretty encapsulation)
    As name suggests extension methods are for extending, not implementing crucial features, I don't ever remember to use extensions to extend my own types, usually used them for types that cannot be changed (3rd party etc.).

    DIM are part of an object and are basically methods - can have access modifiers or attributes, you can make delegates to them easily or use reflections.

    Depends of the usage of IVector3 as I said I would not use interface on struct anyway. In my source I do have IVector3 interface for some classes. Still for pure math operations I use Vector3 provided by unity.

    It is generally a problem with interfaces they are usually boxed.
    He "cheated" a little by specifying that arguments to his methods is "struct". For unknown object he will have boxing anyway but he will have to create all combinations for every possibility.

    But unfortunately his code is buggy (for example you cannot return ref from struct), he might re-post repaired version (compilable) and than we can talk more because it might be not so unproblematic in the end.

    Now I will use DIM when I will see need for them, that does not mean I will use them often.

    I tried my google-fu to find some discussions about this topic but was not successful enough, If you got some link to DIM cons please post It here I will take a look.
     
    sand_lantern likes this.
  14. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    Sadly this is false impression because DIM is actually internally extension method injection in disguise. I don't know if they change the implementation (which is not likely) but the original implementation of DIM is actually extension method

    What I don't like about DIM is actually because it silently introduce things automatically. Extension method allow me to see and control what's going on. And not having the same problem as multiple inheritance

    Seriously, we migrate to C# to avoid bloatness and bugginess of C++ from the start but DIM try to drag us back to that hell again

    As I said, sure I admit there really is `5% of the times that you really really need to implement DIM and extension method cannot do the trick at all`. But as far as I can see, even you yourself cannot think about a real usage that really require DIM. And you can just think of the things that already possible right now with extension method, so there is no value to wait for DIM at all

    There was also a feature request to allow static function and member inside interface. And also feature request to allow extension method in any class, for better encapsulation as you want. And that's fine, that's not DIM and it cannot be overridden, has no problem of multiple inheritance, not related to instance method of interface

    That's why I said that anyone in game industry should not use DIM and so unity don't need to implement it. Because currently now our direction of game industry tend to use as much struct as possible. We have no point to use class. Next step of us is using ECS and we should push more of things that need to be class into framework and make it a solid plain class

    So what you need DIM for again?
     
    koirat likes this.
  15. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    Unfortunately after investigating it a little more I have to admit they are to limited for practical use.

    They are not accessible through concrete class implementation without casting to interface.
    You cannot override virtual DIM method in class.
    And you cannot access protected DIM inside class.


    btw. Are you sure DIMs are implemented by extension methods ?
    I was able to do:
    Action foo = DIM; (for parameterles DIM)
     
    JoNax97 likes this.
  16. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    DIM implemented as not abstract methods inside the interface. they are not extension methods.

    Take a look at this il disassemble https://sharplab.io/#v2:C4LglgNgPgA...oAlI2YMUzZZnlMAvmtVLmbTADkxwLr35DRk2QG5U6oA==

    you cat see that both methods are just interface members. But `NotDefaultMethod` marked as abstract, and DefaultMethod doesn't have abstract modifier
     
  17. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    That was the very first implementation I remember at the time they start playing around with it (3 years ago maybe?). I don't care about it for such a long time and don't have any idea is it have change any implementation already so maybe now is not anymore
     
  18. Walter_Hulsebos

    Walter_Hulsebos

    Joined:
    Aug 27, 2015
    Posts:
    46
    Way to get this thread off the rails guys, good job.
     
    tonygiang, Elringus and JoNax97 like this.
  19. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,476
    So conclusion as of now? Unity support C# 8.0? 9.0? or what? up to?
     
  20. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    As of Unity 2020.2, C# 8 is officially supported (although it uses a version of Roslyn with a bug related to ref structs, unfortunately). You can use C# 9 by updating the Roslyn compiler and using a csc.rsp file to set the language version, but it's obviously not officially supported.
     
    slimshader likes this.
  21. Qbit86

    Qbit86

    Joined:
    Sep 2, 2013
    Posts:
    487
    And what about .NET Standard 2.1? The attributes for nullability annotations from C# 8 are not available in .NET Standard 2.0.
     
  22. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    You can define the attributes yourself and use them with no problems in .NET Standard 2.0, which I'm currently doing. The main downside is needing "#nullable enable" at the top of files, but even that could probably be worked around via the RSP file. The standard library is of course not annotated though, you're just able to annotate your own code.

    Edit: Here's the .cs file that'll allow you to use the annotations: https://gist.github.com/DaZombieKiller/347598dce69d3a03d29f76e63d04650d
     
  23. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    @JoshPeterson is it known bug?
     
  24. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    Here's some simple code to reproduce the compile error (unfortunately, I don't know the exact Roslyn commit it was fixed in, just that the build included with Unity predates it)
    Code (CSharp):
    1. ref struct Example
    2. {
    3.     public Example Method()
    4.     {
    5.         // If a ref struct is stored in a local as the result of a switch expression, you get a compile error if you attempt to return the value.
    6.         var value = 0 switch { _ => new Example() };
    7.  
    8.         // error CS8352: Cannot use local 'value' in this context because it may expose referenced variables outside of their declaration scope
    9.         return value;
    10.     }
    11. }
     
  25. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    No, I was unaware of this bug.

    @TheZombieKiller: thanks for the case to cause this bug. Can you submit a bug report so that we can track this as and correct it?
     
  26. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    I was initially hesitant to as it's not actually a bug in Unity itself, just a result of Unity using an older version of Roslyn (and it had been stated that it would be updated eventually). Since you requested it, I've now made a tracking bug report for it. Case number: 1303638.
     
  27. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    Thanks for submitting it, we will investigate!
     
  28. RunninglVlan

    RunninglVlan

    Joined:
    Nov 6, 2018
    Posts:
    182
  29. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    Can you submit a bug report for this issue?

    https://unity3d.com/unity/qa/bug-reporting
     
    RunninglVlan likes this.
  30. RunninglVlan

    RunninglVlan

    Joined:
    Nov 6, 2018
    Posts:
    182
    OK, this is a strange one. Couldn't reproduce it by just having string starting with @$ in a new project in a MonoBehaviour attached to a GO in a scene.
    This happens only if the script has another class in it with the string starting with @$ and both Mono and that class are wrapped in a namespace.
    Case 1304285
     
    jasonboukheir and JoshPeterson like this.
  31. ilyaylm

    ilyaylm

    Joined:
    Aug 20, 2015
    Posts:
    19
    Need System.Range and Index!!!!!
    This is soooooooo useful
     
    Rijicho_nl and JesseSTG like this.
  32. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    187
    Current solution is to use extension method on the interface. Regarding IObjectId, it seems like you need base (possibly abstract class) not an interface. How would SetObjectId be implemented? Interfaces can't have fields (only accessors) so SetObjectId would have to set the Id property via public setter which would still require derived class to provide the actual Id property.
     
    Walter_Hulsebos likes this.
  33. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    In theory it would work, but in practice it would have a lot of potential for errors. Default implementation also applies to properties setter / getters, but the problem is that the property of the default implementation can have a different value than the value of the implemented version of the property. Within a class / scruct that implements the interface you then have to specify whether you want to use the property on the interface or on your own class.
    This means that a default implementation of a set method sets the value of the property of the defaultinterface property, not the value of the implemented property.
     
  34. VolodymyrBS

    VolodymyrBS

    Joined:
    May 15, 2019
    Posts:
    150
    @JoshPeterson Is there any chance to get Roslyn 3.8.0(or newer) in Unity 2021.1? or in 2021 release cycle in general?
     
  35. xoofx

    xoofx

    Unity Technologies

    Joined:
    Nov 5, 2016
    Posts:
    417
    We have a stretch goal to bring support for latest stable Roslyn to 2021.2 - including support for source generators. While you should be able to target langVersion 9.0, a few features from this version that require new attributes currently only available in .NET 5.0+ Runtime might not be supported out-of-the-box (e.g SkipLocalInits, or init properties)
     
  36. jasonboukheir

    jasonboukheir

    Joined:
    May 3, 2017
    Posts:
    84
    I'd like to know if C# 9 function pointers could be supported out of the box in Burst, or if there's an update that would be necessary to support them. Here's a link to their proposal: https://docs.microsoft.com/en-us/do...erence/proposals/csharp-9.0/function-pointers

    At the moment, getting Burst-compatible lambdas is a tricky business requiring post processing. Unity's
    FunctionPointer
    struct doesn't support generics.
     
    quabug likes this.
  37. xoofx

    xoofx

    Unity Technologies

    Joined:
    Nov 5, 2016
    Posts:
    417
    We haven't been able to test/verify it but, yes, it should. Burst should support the underlying IL opcode (calli) that is being used when calling function pointers in C# 9.0
     
  38. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    987
    How do you "enable enable nullable reference types per library / code fragment"? I just upgraded to Unity 2020.2.2.
     
  39. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    Unity currently does not have a method for doing this at the library level (e.g. in the .asmdef file). You can enable it project wide by passing command line parameters to the Roslyn compiler by adding a csc.rsp file to the project though: https://github.com/dotnet/roslyn/bl...pes.md#setting-project-level-nullable-context
     
    Walter_Hulsebos and davenirline like this.
  40. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    It can also be done per .cs file by adding a "#nullable enable" directive at the top.
     
    davenirline likes this.
  41. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    987
    How do I make it such that violations to such rules are considered as errors instead of just warnings?
     
  42. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    987
    Sorry for the dumb question. Where do I get the csc.rsp file?
     
  43. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    266
    It's just a normal text file that you create and place in your 'Assets' directory (or next to an asmdef as of 2019.2, if I remember right). It contains arguments to pass to the C# compiler, eg "-nullable:enable".

    You can add "-warnaserror" to your csc.rsp file.
     
    davenirline likes this.
  44. davenirline

    davenirline

    Joined:
    Jul 7, 2010
    Posts:
    987
    Thanks!
     
  45. Odminnimda

    Odminnimda

    Joined:
    May 7, 2020
    Posts:
    4
    still nothing?
     
    MilenaRocha likes this.
  46. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    Correct, unfortunately I don't have any updates now.
     
  47. Jorhoto

    Jorhoto

    Joined:
    May 7, 2019
    Posts:
    99
    Interfaces can't have fields, but they can have properties that via default implementation (once available) you could assign a default value.
     
  48. runner78

    runner78

    Joined:
    Mar 14, 2015
    Posts:
    792
    But here there is the problem that the default implementation is only available if you use the interface as a type, and in the implementing class you have to prefix the name of the property with the name of the interface when using the properties. When the class then implemented the property, the default implementation of methods still uses the default implementation. That can quickly lead to errors if you don't take that into account.
     
  49. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    225
    Pretty sure this will box regardless of where
     
    jGate99 likes this.
  50. ScottKane

    ScottKane

    Joined:
    Aug 24, 2019
    Posts:
    81
    @TheZombieKiller is the langversion '9' or '9.0' and how are you using a different version of Roslyn? I'm getting 3.5.0-dev-20359-01 which I assume is packaged somewhere with Unity?