In your question's code, youYou have used conditionals to parse multiple booleans into a Flags enum. ThatWhich is a fine way to do it, but it iscan become quite project specific. IfSay you have a very big enumenum; you'll need to write nested conditionals for each combination of booleans, making. Doing so would make make the code unnecessarily verbose, andas you would need to do that everywhere you want to convert sets of booleans into enums.
The solution below solves this problem by usingBy bypassing type safety, casting to object, and assuming the flag enum is numbered sequentially we can reduce the verbosity. We can then use extension methods and generics to convert arrays of booleans into and from arbitrary enums.
So instead Instead of GetContactPreferences( false, true, false )
you would dowe can instead use new []{ false, true, false }.ToFlagEnum<UserContactPreferences>()
to get the enum.
Note that these extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
ConvertConverting the flag enum to a bool[]boolean array:
Convert thea bool array back to thea flag enum:
With this solution, you can 'parse' sequences of booleans into any Flags enum without writing project-specific logic.
In your question's code, you used conditionals to parse multiple booleans into a Flags enum. That is a fine way to do it, but it is project specific. If you have a very big enum you'll need to write nested conditionals for each combination of booleans, making the code unnecessarily verbose, and you would need to do that everywhere you want to convert sets of booleans into enums.
The solution below solves this problem by using extension methods and generics to convert arrays of booleans into and from arbitrary enums.
So instead of GetContactPreferences( false, true, false )
you would do new []{ false, true, false }.ToFlagEnum<UserContactPreferences>()
to get the enum.
Note that these extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
Convert the flag enum to a bool[]:
Convert the bool array back to the flag enum:
With this solution, you can 'parse' sequences of booleans into any Flags enum without writing project-specific logic.
You have used conditionals to parse multiple booleans into a Flags enum. Which is a fine, but can become quite project specific. Say you have a very big enum; you'll need to write nested conditionals for each combination of booleans. Doing so would make make the code unnecessarily verbose, as you would need to do that everywhere you want to convert sets of booleans into enums.
By bypassing type safety, casting to object, and assuming the flag enum is numbered sequentially we can reduce the verbosity. We can then use extension methods and generics to convert arrays of booleans into and from arbitrary enums. Instead of GetContactPreferences( false, true, false )
we can instead use new []{ false, true, false }.ToFlagEnum<UserContactPreferences>()
to get the enum.
Converting the flag enum to a boolean array:
Convert a bool array to a flag enum:
- 131
- 3
In your question's code, you used conditionals to parse multiple individual booleans into a Flags enum. That is a fine way to do it, but it is project specific, and if. If you have a very big enough enum it's not a scalable approach. One advantageyou'll need to write nested conditionals for each combination of your solution isbooleans, making the code unnecessarily verbose, and you would need to do that it is type-safeeverywhere you want to convert sets of booleans into enums.
MyThe solution is not type-safe. It's basically just a waybelow solves this problem by using extension methods and generics to convert the Flag enum toarrays of booleans into and from an arrayarbitrary enums.
So instead of GetContactPreferences( false, true, false)
you would do new []{ false, true, false )}.ToFlagEnum<UserContactPreferences>()
to get the enum.
Again,Note that these extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
With this solution, you can 'parse' sequences of booleans into any Flags enum without writing project-specific logic.
If you wanted to, you could wrap it in your existing method to provide a familiar interface like this:
UserContactPreferences GetContactPreferences(bool email, bool phone, bool sms)
{
return new []{true,email,phone,sms}.ToFlagEnum<UserContactPreferences>();
}
In your question's code, you used conditionals to parse multiple individual booleans into a Flags enum. That is a fine way to do it, but it is project specific, and if you have a big enough enum it's not a scalable approach. One advantage of your solution is that it is type-safe.
My solution is not type-safe. It's basically just a way to convert the Flag enum to and from an array.
So instead of GetContactPreferences( false, true, false)
you would do new []{ false, true, false ).ToFlagEnum<UserContactPreferences>()
to get the enum.
Again, these extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
In your question's code, you used conditionals to parse multiple booleans into a Flags enum. That is a fine way to do it, but it is project specific. If you have a very big enum you'll need to write nested conditionals for each combination of booleans, making the code unnecessarily verbose, and you would need to do that everywhere you want to convert sets of booleans into enums.
The solution below solves this problem by using extension methods and generics to convert arrays of booleans into and from arbitrary enums.
So instead of GetContactPreferences( false, true, false)
you would do new []{ false, true, false }.ToFlagEnum<UserContactPreferences>()
to get the enum.
Note that these extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
With this solution, you can 'parse' sequences of booleans into any Flags enum without writing project-specific logic.
If you wanted to, you could wrap it in your existing method to provide a familiar interface like this:
UserContactPreferences GetContactPreferences(bool email, bool phone, bool sms)
{
return new []{true,email,phone,sms}.ToFlagEnum<UserContactPreferences>();
}
- 131
- 3
TheseIn your question's code, you used conditionals to parse multiple individual booleans into a Flags enum. That is a fine way to do it, but it is project specific, and if you have a big enough enum it's not a scalable approach. One advantage of your solution is that it is type-safe.
My solution is not type-safe. It's basically just a way to convert the Flag enum to and from an array.
So instead of GetContactPreferences( false, true, false)
you would do new []{ false, true, false ).ToFlagEnum<UserContactPreferences>()
to get the enum.
Again, these extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
Convert the flag enum to a bool[]:
public static bool[] ToBoolArray<T>( this T @enum ) where T : Enum
{
var values = ( int[] )Enum.GetValues( @enum.GetType() );
var arr = new bool[ values.Length + 1 ];
for ( var i = 0; i < arr.Length; i++ )
{
arr[ i ] = @enum.HasFlag( ( T )( object )( 1 << i ) );
}
return arr;
}
Convert the bool array back to the flag enum:
public static T ToFlagEnum<T>( this bool[] arr ) where T : struct
{
if ( typeof( T ).BaseType != typeof( Enum ) )
{
throw new TypeAccessException( "This extension method is for flag enums" );
}
var @enum = default( T );
for ( var i = 0; i < arr.Length; i++ )
{
if ( arr[ i ] )
{
@enum = ( T )( object )( ( int )( object )@enum | ( 1 << i ) );
}
}
return @enum;
}
These extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
Convert the flag enum to a bool[]:
public static bool[] ToBoolArray<T>( this T @enum ) where T : Enum
{
var values = ( int[] )Enum.GetValues( @enum.GetType() );
var arr = new bool[ values.Length + 1 ];
for ( var i = 0; i < arr.Length; i++ )
{
arr[ i ] = @enum.HasFlag( ( T )( object )( 1 << i ) );
}
return arr;
}
Convert the bool array back to the flag enum:
public static T ToFlagEnum<T>( this bool[] arr ) where T : struct
{
if ( typeof( T ).BaseType != typeof( Enum ) )
{
throw new TypeAccessException( "This extension method is for flag enums" );
}
var @enum = default( T );
for ( var i = 0; i < arr.Length; i++ )
{
if ( arr[ i ] )
{
@enum = ( T )( object )( ( int )( object )@enum | ( 1 << i ) );
}
}
return @enum;
}
In your question's code, you used conditionals to parse multiple individual booleans into a Flags enum. That is a fine way to do it, but it is project specific, and if you have a big enough enum it's not a scalable approach. One advantage of your solution is that it is type-safe.
My solution is not type-safe. It's basically just a way to convert the Flag enum to and from an array.
So instead of GetContactPreferences( false, true, false)
you would do new []{ false, true, false ).ToFlagEnum<UserContactPreferences>()
to get the enum.
Again, these extension methods are not 'type safe'. They rely on casting to object and assume that the flag enum is numbered sequentially.
Convert the flag enum to a bool[]:
public static bool[] ToBoolArray<T>( this T @enum ) where T : Enum
{
var values = ( int[] )Enum.GetValues( @enum.GetType() );
var arr = new bool[ values.Length + 1 ];
for ( var i = 0; i < arr.Length; i++ )
{
arr[ i ] = @enum.HasFlag( ( T )( object )( 1 << i ) );
}
return arr;
}
Convert the bool array back to the flag enum:
public static T ToFlagEnum<T>( this bool[] arr ) where T : struct
{
if ( typeof( T ).BaseType != typeof( Enum ) )
{
throw new TypeAccessException( "This extension method is for flag enums" );
}
var @enum = default( T );
for ( var i = 0; i < arr.Length; i++ )
{
if ( arr[ i ] )
{
@enum = ( T )( object )( ( int )( object )@enum | ( 1 << i ) );
}
}
return @enum;
}