Skip to content

Conversation

@jnyrup
Copy link
Member

@jnyrup jnyrup commented Apr 19, 2020

In C# 7.3 the enum constraint was introduced, which lets us restrict the parameter of [Not]HaveFlag to a struct enum.

This prevents an NRE if one passed in null - as it no longer compiles.

@dennisdoomen
Copy link
Member

What does that do to the binary and source-code compatibility?

@jnyrup jnyrup requested a review from dennisdoomen April 20, 2020 05:45
@jnyrup
Copy link
Member Author

jnyrup commented Apr 20, 2020

Currently one can pass in null to HaveFlag, as the parameter is Enum is a reference type, causing an NRE.

using System;
public class Program {
    enum MyEnum
    {
        A
    }
    
    static bool Foo(Enum t)
        => MyEnum.A.HasFlag(t);
    
    static bool Bar<TEnum>(TEnum t)
        where TEnum : struct, Enum 
        => MyEnum.A.HasFlag(t);

    static bool Baz<TEnum>(TEnum t)
        where TEnum : Enum 
        => MyEnum.A.HasFlag(t);
   
    
    static void Main()
    {
        MyEnum nativeEnum = MyEnum.A;
        Enum classEnum = MyEnum.A;
        Enum nullEnum = null;
        
        Foo(nativeEnum);
        Foo(classEnum);
        Foo(nullEnum); // NRE
        
        Bar(nativeEnum);
        //Bar<MyEnum>(classEnum); // does not compile
        //Bar<MyEnum>(nullEnum); // does not compile

        Baz(nativeEnum);
        Baz(classEnum);
        Baz(nullEnum); // NRE
    }       
}

https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQxAgrgOwD4AEBMAjALABQuAzAAQE2EDsVA3mVW1XJumFQLICeAUS5hW7FqXZSqAQTFsAvvKrLchAGxVgAe20AbKgDFdACmHcqMAJTKpAXgB8fISIB0M1wAlohvRADmJtYA3MqqGlq6BgBCEAgAPAAq5mAOJskiljaS0mwA7gAWiHBUGRYgVLAYAMYwSFQpKjm5js4p7l4+foEhZOGaOvpUsQBeSSlpZTzWtuyFxaWNFY2zbK0C7R7eUL4BQVahzWHNdJq4ACx8EACWmCbZUhK5bBuZmBAw1wBucI12bW4ZIdng1MgQ/gDuO5gc9Glw9HoIfC9DDcqsjKZ3p8fikDujjNoTOCRHiTlICSZkbjglQAPS0qgAOQASoJ0ejYghKR9vr8SajpPTOfFXtw0sTuAc6QyACbaOBQKiYbQwKjVbRgAAO1z0cHRQriIpcYsp6AR1OlVDlCqVKrVGu1ur6ZPYo252L5koFUjdErApJBbqp/MtLLZJwUzzICiAA

Reading up on the initial implementation in #250 it seems the only/main reason this wasn't moved to a separate EnumAssertions class was the lack of enum constraints which we now have.

It has nice potential.
E.g.

MyEnum.A.Should().Be(OtherEnum.A)
MyEnum.A.Should().Be((object)42)

will simply be turned into compile time errors.

@jnyrup jnyrup marked this pull request as draft April 20, 2020 17:05
@NN---
Copy link

NN--- commented May 15, 2020

Will it be merged? Why the PR is still draft.

@jnyrup jnyrup closed this Aug 12, 2020
@jnyrup jnyrup deleted the EnumConstraint branch August 18, 2020 14:31
@jnyrup jnyrup restored the EnumConstraint branch October 27, 2020 07:21
@jnyrup jnyrup deleted the EnumConstraint branch January 23, 2021 08:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants