Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. How To : coerce a ref to an enum into a ref to an int.

How To : coerce a ref to an enum into a ref to an int.

Scheduled Pinned Locked Moved C#
tutorialquestion
2 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    urbane tiger
    wrote on last edited by
    #1

    I have a method in a common base class thus : protected bool SetFlag(bool _new, ref int _flags, int _flag, string _pName) { bool __cancelled = false; bool __old = ((_flags & _flag) == _flag); if (!__old.Equals(_new) { if (!(__cancelled = this.RaisePropertyChanging(__old, _new, pName))) { _flags = (_new) ? _flags | _flag : _flags & ~flag; this.RaisePropertyChanged(__old, _new, pName); } } return __cancelled; } In derivatives of the common base I want to use SetFlags as is shown in the example at the end of this post, but I get a message telling me that it can't cast a ref to an AmbientState to an int etc. If I give SetFlag a Type argument then I can only constrain it to a class(reference type) or struct(value type), but in that case I get compile errors stating that bitwise operations cannot be performed on T objects, ie structs. The content of _flags (ambientState in the example) must be changed BEFORE PropertyChanged handlers are invoked. I have a work-around - The _flags parameter is not passed by reference and I've added a delegate method argument to SetFlag that gets invoked between the "flags = ...." and the "this.RaisePropertyChanged...." statements, the delegate looks like private void saveFlags(int _flags) { this.ambientState = (AmbientState) _flags; ) But like all workarounds its ugly and necessitates documenting why the delegate exists etc. Rgds PhilD -- Sample usage of SetFlags follows public class MyClass : CommonBase { AmbientState ambientState = AmbientState.ZeroValue; public bool Morning { get { return ((this.ambientState & AmbientState.Morning) == AmbientState.Morning); } set { this.SetFlag(value, (int) ref this.ambientState, AmbientState.Morning, "Morning"; } } [Flags] private enum AmbientState : int { ZeroValue = 0x0 Morning = 0x1 Afternoon = 0x2 Evening = 0x4 Night = 0x8 ClearSky = 0x10 CirrusSky = 0x02 etc } }

    S 1 Reply Last reply
    0
    • U urbane tiger

      I have a method in a common base class thus : protected bool SetFlag(bool _new, ref int _flags, int _flag, string _pName) { bool __cancelled = false; bool __old = ((_flags & _flag) == _flag); if (!__old.Equals(_new) { if (!(__cancelled = this.RaisePropertyChanging(__old, _new, pName))) { _flags = (_new) ? _flags | _flag : _flags & ~flag; this.RaisePropertyChanged(__old, _new, pName); } } return __cancelled; } In derivatives of the common base I want to use SetFlags as is shown in the example at the end of this post, but I get a message telling me that it can't cast a ref to an AmbientState to an int etc. If I give SetFlag a Type argument then I can only constrain it to a class(reference type) or struct(value type), but in that case I get compile errors stating that bitwise operations cannot be performed on T objects, ie structs. The content of _flags (ambientState in the example) must be changed BEFORE PropertyChanged handlers are invoked. I have a work-around - The _flags parameter is not passed by reference and I've added a delegate method argument to SetFlag that gets invoked between the "flags = ...." and the "this.RaisePropertyChanged...." statements, the delegate looks like private void saveFlags(int _flags) { this.ambientState = (AmbientState) _flags; ) But like all workarounds its ugly and necessitates documenting why the delegate exists etc. Rgds PhilD -- Sample usage of SetFlags follows public class MyClass : CommonBase { AmbientState ambientState = AmbientState.ZeroValue; public bool Morning { get { return ((this.ambientState & AmbientState.Morning) == AmbientState.Morning); } set { this.SetFlag(value, (int) ref this.ambientState, AmbientState.Morning, "Morning"; } } [Flags] private enum AmbientState : int { ZeroValue = 0x0 Morning = 0x1 Afternoon = 0x2 Evening = 0x4 Night = 0x8 ClearSky = 0x10 CirrusSky = 0x02 etc } }

      S Offline
      S Offline
      Skippums
      wrote on last edited by
      #2

      The most obvious solution is to set an int value, call the method with a ref to that value, then reset it to the ambientState property, as follows:

      public bool Morning {
      get { ... }
      set {
      int as = (int)this.ambientState;
      this.SetFlag(value, ref as, ...);
      this.ambientState = (AmbientState)as;
      }
      }

      Another solution I see is doing the reverse, which is probably better, since you cut down on the responsibility of the user, and to impede type checking for your enum type. Do this as follows:

      protected bool SetFlag(bool _new, ref AmbientState _flags, AmbientState _flag, string _pName)
      {
      int flag = (int)_flag;
      int flags = (int)_flags;
      bool __cancelled = false;
      bool __old = ((flags & flag) == flag);
      if (!__old.Equals(_new)
      {
      if (!(__cancelled = this.RaisePropertyChanging(__old, _new, pName)))
      {
      flags = (_new) ? flags | flag : flags & ~flag;
      this.RaisePropertyChanged(__old, _new, pName);
      _flags = (AmbientState)flags;
      }
      }
      return __cancelled;
      }

      And finally, the RECOMMENDED way of doing this, is setting the FlagsAttribute on the enumeration as follows:

      [FlagsAttribute]
      public enum AmbientState {
      ...
      }

      This final way allows you to use &, |, and ^ on the values of the enumeration. I'm not sure if you can use ~, but you can always go to find out! Hope this helps,

      -Jeff

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups