Issues making a generic class with System.Enum as a parameter [modified]
-
What I'd like to be able to do is make a generic class for hardware status words where every bit in the word corresponds to a boolean named flag. I'd like to have something that would take advantage of the underlying type of the enum as well as some attributes that I'm tagging onto the enum. I thought I'd be able to do that, but I'm not having very much luck at it. I guess the enum is just being used as a template which is what I want. The question is, is it possible to take advantage of some of the enum features in a generic class? Example target code:
enum AlarmTemplate : byte { [Description("High Liquid Level")] HighLevel, [Description("Low Liquid Level")] LowLevel } Byte theStatus = 0xA5; StatusWord<<AlarmTemplate>> word = new StatusWord<<AlarmTemplate>>(theStatus); // where i can pass in the underlying type as an initializer word.Bit[AlarmTemplate.HighLevel] = false; // Indexer Byte temp = word.UnderlyingValue; // returns the enum's underlying type
I've always made custom classes to support all of these things, and lately I'm getting tired of it. Any ideas? Scott P“It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.” -Edsger Dijkstra
modified on Thursday, May 8, 2008 11:03 AM
-
What I'd like to be able to do is make a generic class for hardware status words where every bit in the word corresponds to a boolean named flag. I'd like to have something that would take advantage of the underlying type of the enum as well as some attributes that I'm tagging onto the enum. I thought I'd be able to do that, but I'm not having very much luck at it. I guess the enum is just being used as a template which is what I want. The question is, is it possible to take advantage of some of the enum features in a generic class? Example target code:
enum AlarmTemplate : byte { [Description("High Liquid Level")] HighLevel, [Description("Low Liquid Level")] LowLevel } Byte theStatus = 0xA5; StatusWord<<AlarmTemplate>> word = new StatusWord<<AlarmTemplate>>(theStatus); // where i can pass in the underlying type as an initializer word.Bit[AlarmTemplate.HighLevel] = false; // Indexer Byte temp = word.UnderlyingValue; // returns the enum's underlying type
I've always made custom classes to support all of these things, and lately I'm getting tired of it. Any ideas? Scott P“It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.” -Edsger Dijkstra
modified on Thursday, May 8, 2008 11:03 AM
I don't know if I understood you correctly, but how about something like this
class StatusWord<T, U> where T : struct where U : struct { U val; public StatusWord(U val) { this.val = val; } public bool this\[T t\] { set { val = val | 0x001; } } public U Val { get { return val; } } }
Regards Senthil [MVP - Visual C#] _____________________________ My Blog | My Articles | My Flickr | WinMacro
-
What I'd like to be able to do is make a generic class for hardware status words where every bit in the word corresponds to a boolean named flag. I'd like to have something that would take advantage of the underlying type of the enum as well as some attributes that I'm tagging onto the enum. I thought I'd be able to do that, but I'm not having very much luck at it. I guess the enum is just being used as a template which is what I want. The question is, is it possible to take advantage of some of the enum features in a generic class? Example target code:
enum AlarmTemplate : byte { [Description("High Liquid Level")] HighLevel, [Description("Low Liquid Level")] LowLevel } Byte theStatus = 0xA5; StatusWord<<AlarmTemplate>> word = new StatusWord<<AlarmTemplate>>(theStatus); // where i can pass in the underlying type as an initializer word.Bit[AlarmTemplate.HighLevel] = false; // Indexer Byte temp = word.UnderlyingValue; // returns the enum's underlying type
I've always made custom classes to support all of these things, and lately I'm getting tired of it. Any ideas? Scott P“It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.” -Edsger Dijkstra
modified on Thursday, May 8, 2008 11:03 AM
The code you show seems more or less OK (other than the doubled < and >), but I don't understand what you want to accomplish.
carbon_golem wrote:
where every bit in the word corresponds to a boolean named flag
Will the FlagsAttribute be of use?
-
The code you show seems more or less OK (other than the doubled < and >), but I don't understand what you want to accomplish.
carbon_golem wrote:
where every bit in the word corresponds to a boolean named flag
Will the FlagsAttribute be of use?
I put the double <<>> to make the CP html generator show at least that it was generic. What I want to do is define named bits in a generic way. The named bits would be of standard lengths, 8, 16, 32, 64. I hoped to use an enum to provide a templating mechanism to do this, but so far no luck, and the solutions I have worked out aren't very type safe. What this is for is representing bit fields in embedded device logs. Here is my latest. A lot of it is shetchy, but...
public class StatusField where T : struct { #region Members private T template; private ValueType sword; #endregion private StatusField(ValueType initialValue) { template = new T(); if (template is Enum) { Type t = template.GetType(); if (t.GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0) { throw new System.InvalidCastException("Requires Enum that defines FlagsAttribute"); } sword = initialValue; } else { throw new System.InvalidCastException("Could not convert generic type"); } } public Object UnderlyingValue { get { return sword; } set { sword = (ValueType)value; } } public Boolean this[T index] { get { if (Enum.IsDefined(typeof(T), index)) { Object x = Convert.ChangeType(index, typeof(Int64)); Int64 temp1 = (Int64)x; Object y = Convert.ChangeType(sword, typeof(Int64)); Int64 temp2 = (Int64)y; return (temp1 & temp2) == temp1; } else { throw new IndexOutOfRangeException("Field is not defined"); } } set { if (Enum.IsDefined(typeof(T), index)) { // setter not defined } else { throw new IndexOutOfRangeException("Field is not defined"); } } } public static StatusField New(ValueType value) { return new StatusField(value); } }
And Usage:StatusField field = StatusField.New(Alarms.Battery | Alarms.Motion);
-
I put the double <<>> to make the CP html generator show at least that it was generic. What I want to do is define named bits in a generic way. The named bits would be of standard lengths, 8, 16, 32, 64. I hoped to use an enum to provide a templating mechanism to do this, but so far no luck, and the solutions I have worked out aren't very type safe. What this is for is representing bit fields in embedded device logs. Here is my latest. A lot of it is shetchy, but...
public class StatusField where T : struct { #region Members private T template; private ValueType sword; #endregion private StatusField(ValueType initialValue) { template = new T(); if (template is Enum) { Type t = template.GetType(); if (t.GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0) { throw new System.InvalidCastException("Requires Enum that defines FlagsAttribute"); } sword = initialValue; } else { throw new System.InvalidCastException("Could not convert generic type"); } } public Object UnderlyingValue { get { return sword; } set { sword = (ValueType)value; } } public Boolean this[T index] { get { if (Enum.IsDefined(typeof(T), index)) { Object x = Convert.ChangeType(index, typeof(Int64)); Int64 temp1 = (Int64)x; Object y = Convert.ChangeType(sword, typeof(Int64)); Int64 temp2 = (Int64)y; return (temp1 & temp2) == temp1; } else { throw new IndexOutOfRangeException("Field is not defined"); } } set { if (Enum.IsDefined(typeof(T), index)) { // setter not defined } else { throw new IndexOutOfRangeException("Field is not defined"); } } } public static StatusField New(ValueType value) { return new StatusField(value); } }
And Usage:StatusField field = StatusField.New(Alarms.Battery | Alarms.Motion);
I suspect you need the FlagsAttribute, but I'm still unclear on what you are trying to do.