I have a VO class that contains several variables incl. a variable that can be of different types and to prevent casting later on I wonder if I can make that class generic.
public class InputVO<T>
{
public bool isEnabled;
public T value;
}
Then I want to create an array of InputVOs and a method to get a typed InputVO...
public InputVO[] Inputs { get; private set; }
public InputVO GetInput(InputType type)
{
return Inputs[(int)type];
}
How do I go about defining the array and the GetInput method so that they work with the generic InputVO? (The InputType type argument is an enum. Shouldn't really matter here, I think).
Generic type parameters are fixed at compile-time.
Whenever you use InputVO, that type parameter needs to be filled in.
public InputVO<T1>[] Inputs { get; private set; }
But what you seem to want is different InputVO objects for each datatype, and to be able to retrieve them by type at runtime:
// Base class for all InputVOs
public abstract InputVOBase
{
public bool isEnabled;
}
// InputVO for a specific data-type
public class InputVO<T> : InputVOBase
{
public T Value;
}
Now you can use a dictionary from Type to InputVOBase.
// One InputVO per datatype
public Dictionary<Type, InputVOBase> AllInputs { get; private set; }
// Return the VO for type T, or null
public InputVO<T> GetInput<T>()
{
InputVOBase vo = AllInputs[typeof(T)];
return (vo as InputVO<T>);
}
You cannot create an array of a generic class without specifying the type. However, as you have control over the base type, you can make that implement a non generic interface and have a collection of that instead:
//Empty interface
public interface IInputVO { }
//Your generic class now implements the interface
public class InputVO<T> : IInputVO
{
public bool isEnabled { get; set; }
public T Value { get; set; }
}
So now your array is of the interface type IInputVO:
IInputVO[] inputs =
{
new InputVO<int>(),
new InputVO<string>(),
new InputVO<SomeClass>(),
};
Cleaned up solution a bit. Mainly you need to collect your values in a dictionary.
void Main()
{
var a = new InputVO<string> { Value = "test" };
var b = new InputVO<int> { Value = 5 };
Inputs.Add(typeof(string), a);
Inputs.Add(typeof(int), b);
var x = GetInput<string>();
Console.WriteLine(x.Value);
var y = GetInput<int>();
Console.WriteLine(y.Value);
}
public abstract class InputVOBase
{
public bool isEnabled;
}
public class InputVO<T> : InputVOBase
{
public T Value;
}
public Dictionary<Type, InputVOBase> Inputs = new Dictionary<Type, InputVOBase>();
public InputVO<T> GetInput<T>()
{
return Inputs[typeof(T)] as InputVO<T>;
}
Thanks for the tips anyone! Phew, since there's no way getting around casting and I only need to regard a couple of types I think all the generics-based solutions are a bit overkill in my case. So I simply added casted getters to my VO ...
public class InputVO
{
public bool isEnabled;
public bool isValid;
public InputType type;
public object value;
public int IntValue { get { return (int)value; } }
public float FloatValue { get { return (float)value; } }
public bool BoolValue { get { return (bool)value; } }
public Vector2 Vector2Value { get { return (Vector2) value; } }
public Vector3 Vector3Value { get { return (Vector3)value; } }
}
Related
Having the following classes:
public class DeviceParameter
{
public string Key { get; set; }
public Guid DeviceId { get; set; }
public string Value { get; set; }
}
A device can have a lot of parameters, of different types, but they are all stored in the database as strings.
public abstract class DeviceValueTypedParameter<TValue>
{
public string CodeName { get; }
public TValue Value { get; set; }
public Guid DeviceId { get; set; }
public DeviceValueTypedParameter(string codeName)
{
this.CodeName = codeName;
}
}
DeviceValueTypedParameter is an abstraction, to have a typed value (TValue) used on C# of the parameter value, instead of using the string that we get from the database. There is no heritance between DeviceValueTypedDeviceParameter and DeviceParameter because I want to make the conversion from TValue to string by composition.
public class ArmingStatusParameter : DeviceValueTypedParameter<ArmingStatuses>
{
public const string CODE_NAME = "ArmingStatus";
public ArmingStatusParameter() : base(CODE_NAME)
{
}
}
public enum ArmingStatuses
{
Unknown,
Armed,
Disarmed,
}
ArmingStatusParameter is an example of a typed Parameter that can exist, where the value is an Enum of ArmingStatuses. Other types that can exist are DateTimes, int32, double, etc.
I've already accomplished the conversion from Typed value to string, but now I'm struggling how to properly do the conversion from string to Typed value.
Tried different approaches:
Implicit or Explicit conversion
Extension method
Converter classes for each type that exists
Generic converter class based on TValue type
Option 1: is easy to implement, but violates the POCO of
ArmingStatusParameter. People can forget to implement the implicit/explicit operators and errors will only happen at compile time.
Option 2: violates the Interface segregation principle (ISP), since is needed to access directly the conversion.
Option 3: it works, but people will have to create a lot of classes and the code will be too verbose. For each different parameter, is needed to instance a new {X}TypedParameterConverter.
Option 4: seems the best option, but I am having troubles "in making it work"
I was thinking about something like this:
public interface IDeviceValueTypedParameterConverter
{
bool TryConvert<T, TValue>(DeviceParameter deviceParameter,
DeviceValueTypedParameter<TValue> deviceValueTypedParameter)
where T : DeviceValueTypedParameter<TValue>;
}
public class DeviceValueTypedParameterConverter : IDeviceValueTypedParameterConverter
{
public bool TryConvert<T, TValue>(DeviceParameter inputParameter,
DeviceValueTypedParameter<TValue> outputParameter)
where T : DeviceValueTypedParameter<TValue>
{
bool result = true;
if (inputParameter == null)
{
throw new NullReferenceException($"DeviceValueTypedParameter:'{typeof(T)}' must be initialized first");
}
if (inputParameter.Value is int)
{
result = int.TryParse(inputParameter.Value, out int temp);
outputParameter.Value = (TValue)temp;
}
else if (inputParameter.Value is Enum)
{
// some other code to convert the Enum's
}
// more else ifs one for each type
// (...)
else
{
result = false;
}
outputParameter.DeviceId = inputParameter.DeviceId;
return result;
}
}
Issues:
All the Ifs gives me a warning saying: "The given expression is never of the provided".
Can't make the cast (TValue). It says can't convert int to TValue. The only solution is creating value via reflection?
Here is my attempt to make this work - I am not sure if it violates some details you did not explain (or did explain). Since out parameters can't use polymorphism, I created an interface to represent the common functions across the typed parameter base class. Since there are no static virtual methods, I used object methods and created a result object that will is used if the conversion is possible.
I see no reason for the conversion method to have multiple instances or need an interface, so I created it as a single static method. I used an enum to capture the type of conversion needed for the parameter accessible from the passed in type, and had to do a tricky conversion through object to handle assignment to the out parameter value field, since C# has no type switching capability for assignments. Note this could cause a runtime error if the IsPossible method doesn't properly filter all cases and the ChangeType fails.
public enum ValueParseTypes {
Enum,
DateTime,
Int
}
public interface IDeviceValueTypedDeviceParameter<TValue> {
string CodeName { get; }
TValue Value { get; set; }
Guid DeviceId { get; set; }
ValueParseTypes ParseType { get; set; }
bool IsPossibleValue(DeviceParameter aValue);
}
public abstract class DeviceValueTypedDeviceParameter<TValue> : IDeviceValueTypedDeviceParameter<TValue> {
public string CodeName { get; }
public TValue Value { get; set; }
public Guid DeviceId { get; set; }
public ValueParseTypes ParseType { get; set; }
public DeviceValueTypedDeviceParameter(string codeName, ValueParseTypes parseType) {
this.CodeName = codeName;
this.ParseType = parseType;
}
public virtual bool IsPossibleValue(DeviceParameter aValue) => false;
}
public class ArmingStatusParameter : DeviceValueTypedDeviceParameter<ArmingStatuses> {
public const string CODE_NAME = "ArmingStatus";
public ArmingStatusParameter() : base(CODE_NAME, ValueParseTypes.Enum) {
}
static HashSet<string> ArmingStatusesNames = Enum.GetNames(typeof(ArmingStatuses)).ToHashSet();
public override bool IsPossibleValue(DeviceParameter aValue) => ArmingStatusesNames.Contains(aValue.Value);
}
public enum ArmingStatuses {
Unknown,
Armed,
Disarmed,
}
public class PoweredOnStatusParameter : DeviceValueTypedDeviceParameter<DateTime> {
public const string CODE_NAME = "PoweredOn";
public PoweredOnStatusParameter() : base(CODE_NAME, ValueParseTypes.DateTime) {
}
public override bool IsPossibleValue(DeviceParameter aValue) => DateTime.TryParse(aValue.Value, out _);
}
public class VoltageStatusParameter : DeviceValueTypedDeviceParameter<int> {
public const string CODE_NAME = "PoweredOn";
public VoltageStatusParameter() : base(CODE_NAME, ValueParseTypes.Int) {
}
public override bool IsPossibleValue(DeviceParameter aValue) => Int32.TryParse(aValue.Value, out _);
}
public static class DeviceValueTypedParameterConverter {
public static bool TryConvert<TValue>(DeviceParameter inputParameter, IDeviceValueTypedDeviceParameter<TValue> outputParameter)
where TValue : struct {
if (inputParameter == null)
throw new ArgumentNullException(nameof(inputParameter));
else if (outputParameter == null)
throw new ArgumentNullException(nameof(outputParameter));
bool result = false;
if (outputParameter.IsPossibleValue(inputParameter)) {
outputParameter.DeviceId = inputParameter.DeviceId;
switch (outputParameter.ParseType) {
case ValueParseTypes.Enum:
if (Enum.TryParse(inputParameter.Value, out TValue typedValue)) {
outputParameter.Value = typedValue;
result = true;
}
break;
case ValueParseTypes.DateTime:
if (DateTime.TryParse(inputParameter.Value, out var dtValue)) {
outputParameter.Value = (TValue)Convert.ChangeType(dtValue, typeof(TValue));
result = true;
}
break;
case ValueParseTypes.Int:
if (Int32.TryParse(inputParameter.Value, out var intValue)) {
outputParameter.Value = (TValue)Convert.ChangeType(intValue, typeof(TValue));
result = true;
}
break;
}
}
return result;
}
}
Now you can use it like so:
var as_tv = new DeviceParameter() {
Key = "testkey",
DeviceId = new Guid(),
Value = "Armed"
};
var asp = new ArmingStatusParameter();
if (DeviceValueTypedParameterConverter.TryConvert<ArmingStatuses>(as_tv, asp)) {
// work with asp
}
var po_tv = new DeviceParameter() {
Key = "testkey2",
DeviceId = new Guid(),
Value = "4/15/2019 17:36"
};
var pop = new PoweredOnStatusParameter();
if (DeviceValueTypedParameterConverter.TryConvert<DateTime>(po_tv, pop)) {
// work with pop
}
var v_tv = new DeviceParameter() {
Key = "testkey3",
DeviceId = new Guid(),
Value = "17"
};
var vp = new VoltageStatusParameter();
if (DeviceValueTypedParameterConverter.TryConvert<int>(v_tv, vp)) {
// work with vp
}
I have base class that save all property value in a Dictionary. but I want to property value and value in Dictionary has save value. if property value change then change dictionary value and if change value in dictionary , change property value. In Constructor I use reflection but after finish constructor I want not used reflection because of performance.
Type of dictionary value is following (in my project its more complex):
public class AgentProperty
{
public object Value;
public string Name;
public AgentProperty(string name, object value)
{
Value = value;
Name = name;
}
}
The Base Class is following:
public class BaseClass
{
private Dictionary<string,AgentProperty> Dictionary = new Dictionary<string, AgentProperty>();
public AgentProperty this[string key]
{
get { return (AgentProperty)Dictionary[key]; }
set { Dictionary[key] = value; }
}
public void Add(AgentProperty ap)
{
Dictionary.Add(ap.Name, ap);
}
public void SetDict(BaseClass o)
{
var objectType = o.GetType();
foreach (var property in objectType.GetProperties())
{
AgentProperty agentProperty = new AgentProperty(property.Name, property.GetValue(o));
Add(agentProperty);
}
}
}
The sample class that inherited from BaseClass. This class can have any type of property.
public class TmpClass : BaseClass
{
public TmpClass(){
SetDict(this);
}
public string X { get; set; }
public int y { get; set; }
public string Z { get; set; }
public TimeSpan T { get; set; }
}
Is there any way to do this?
I am trying to automate the display (gathering via reflection) of my variables which are located in specific scripts in Unity. The trouble is assigning custom values (for example: "string DisplayName", "bool DisplayMe", "bool WriteMe" etc.). When it comes to my custom classes I understand how I would do it, but I would like to avoid remaking types like float, string, int etc. for this purpose.
For example, let's say I have:
public class myBaseClass
{
public string Name = "Display Name";
public bool AmReadable = true;
public bool AmWritable = true;
}
Then:
public class myDoubleFloat: myBaseClass
{
public float ValueFirst;
public float ValueSecond;
}
So in some scripts in Unity I define it:
public class SomeScriptOnGameObject : MonoBehaviour
{
public myDoubleFloat myFirstVariable{get; set;}
public float mySecondVariable{get; set;}
}
So later on with reflection I can check whether "myFirstVariable" should be read, it's display name etc. - while for "mySecondVariable" I cannot perform this check. How do I go about this without reinventing the wheel and making a class for each of these types like float, string, int, List etc.?
You can define a generic wrapper:
public class MyProperty<T>
{
private T _value;
public T Get() => _value;
public T Set(T newValue) => _value = newValue;
public string Name { get; set; }
public bool AmReadable { get; set; }
public bool AmWritable { get; set; }
}
And make your properties's getters and setter to map to some backing fields of type MyProperty<T>:
public class SomeScriptOnGameObject : MonoBehaviour
{
private MyProperty<MyDoubleFloat> _myFirstVariable;
private MyProperty<float> _mySecondVariable;
public MyDoubleFloat MyFirstVariable
{
get => _myFirstVariable.Get();
set => _myFirstVariable.Set(value);
}
public float MySecondVariable
{
get => _mySecondVariable.Get();
set => _mySecondVariable.Set(value);
}
public SomeScriptOnGameObject()
{
_myFirstVariable = new MyProperty<MyDoubleFloat>
{
//configuration
};
_mySecondVariable = new MyProperty<float>
{
//configuration
};
}
}
If you want to be fancy you can even add an implicit operator to get rid of Get() and make any T assignable from MyProperty<T>:
public class MyProperty<T>
{
private T _value;
public T Set(T newValue) => _value = newValue;
public string Name { get; set; }
public bool AmReadable { get; set; }
public bool AmWritable { get; set; }
public static implicit operator T(MyProperty<T> myProperty) =>
myProperty != null ? myProperty._value : default;
}
And:
public MyDoubleFloat MyFirstVariable
{
get => _myFirstVariable;
set => _myFirstVariable.Set(value);
}
Wrapping value objects (int, float, etc.) is probably not the best approach. Besides the additional complexity (and possibility for bugs), you are now bloating the memory footprint of your game.
(I'm intentionally avoiding newer C# syntax in these examples)
Since you are already in a reflection context, instead of wrapping your value objects, I'd suggest an attribute-based approach. For example:
public class SomeScriptOnGameObject
{
[DisplayName("First Variable"), Writable]
public float FirstVariable { get; set; }
[DisplayName("Second Variable")]
public float SecondVariable { get; set; }
[DisplayName("Some Field")]
public float Field;
public float FieldWithNoAttributes;
}
This has the advantage of keeping the metadata of the fields in the metadata, instead of carrying around a copy of everything with every instance you create.
The actual attributes are easy to create, also. I'll start with the simplest one, WritableAttribute:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class WritableAttribute : Attribute
{
}
This empty class is all that's needed to mark a field or property as "Writable". The AttributeUsage marks this as only valid on fields and properties (not, for example, a class).
The other attribute, DisplayName, is only slightly more complex:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class DisplayNameAttribute : Attribute
{
public string DisplayName { get; private set; }
public DisplayNameAttribute(string displayName)
{
DisplayName = displayName;
}
}
The main difference is the constructor with the displayName argument, and the DisplayName property. This forces the compiler to expect an argument to the attribute.
With some extension methods, you can make things very clean:
public static class AttributeExtensions
{
public static bool IsWritable(this MemberInfo memberInfo)
{
return memberInfo.GetCustomAttributes(typeof(WritableAttribute)).Any();
}
public static string DisplayName(this MemberInfo memberInfo)
{
var displayNameAttribute =
memberInfo.GetCustomAttributes(typeof(DisplayNameAttribute))
.FirstOrDefault() as DisplayNameAttribute;
return displayNameAttribute == null ? null : displayNameAttribute.DisplayName;
}
public static PropertyInfo Property<T>(this T _, string propertyName)
{
return typeof(T).GetProperty(propertyName);
}
public static FieldInfo Field<T>(this T _, string fieldName)
{
return typeof(T).GetField(fieldName);
}
}
(Since you mentioned you are already using reflection, you might not need the last two methods there.)
Finally, a simple XUnit test to demonstrate:
public class UnitTest1
{
[Fact]
public void Test1()
{
var obj = new SomeScriptOnGameObject();
Assert.True(obj.Property("FirstVariable").IsWritable());
Assert.False(obj.Property("SecondVariable").IsWritable());
Assert.False(obj.Field("Field").IsWritable());
Assert.Equal("First Variable", obj.Property("FirstVariable").DisplayName());
Assert.Equal("Second Variable", obj.Property("SecondVariable").DisplayName());
Assert.Equal("Some Field", obj.Field("Field").DisplayName());
Assert.Null(obj.Field("FieldWithNoAttributes").DisplayName());
}
}
I want to pass a list/dictionary of generic parameter (that can be different types in the same collection) to a method in a modular application.
I hope my code can explain it better.
The interfaces:
public interface IField
{ }
public interface IField<T> : IField
{
T Value { get; }
}
The implemented class:
public class Field<T> : IField<T>
{
public Field(T value)
{
Value = value;
}
public T Value { get; set; }
}
Now I can create a Dictionary with my parameters and call a method that is implemented in a different assembly not referenced (I get it using reflection):
static void Main(string[] args)
{
var dicFields = new Dictionary<string, IField>();
dicFields.Add("param1", new Field<string>("Hello"));
dicFields.Add("param2", new Field<int>(15));
MyMethod(dicFields);
}
Now, in 'MyMethod', I want to get the value for a specific parameter in the dictionary:
public void MyMethod(IDictionary<string, IField> parameters)
{
var param2 = parameters["param2"];
}
The problem is that 'param2' has not the property Value (generic type) because I used the IField interface to define the dictionary elements and in 'MyMethod' we can't know the right implementation of the parameter.
Any suggestion to achieve my goal?
Generics do not work this way.
To get the Generic Types, you need to use the IField<T> interface in your dictionary and your method.
However, you aren't going to be able to mix types because when you create an instance of a class you IField will be restricted to only T:
public interface IField
{
}
public interface IField<T> : IField
{
T Value { get; }
}
public class Field<T> : IField<T>
{
public Field(T value)
{
Value = value;
}
public T Value { get; set; }
}
public void Generic()
{
var dicFields = new Dictionary<string, IField<string>>();
dicFields.Add("param1", new Field<string>("Hello"));
dicFields.Add("param2", new Field<string>("Hello"));
MyMethod<String>(dicFields);
}
public void MyMethod<T>(IDictionary<string, IField<T>> parameters)
{
var param2 = parameters["param2"].Value;
}
If you wanted to mix types you would need to use IField which will require you to box and unbox your types:
public interface IField
{
}
public interface IField<T> : IField
{
T Value { get; }
}
public class Field<T> : IField<T>
{
public Field(T value)
{
Value = value;
}
public T Value { get; set; }
}
public void Generic()
{
var dicFields = new Dictionary<string, IField<object>>();
dicFields.Add("param1", new Field<object>("Hello"));
dicFields.Add("param2", new Field<object>(2));
MyMethod<object>(dicFields);
}
public void MyMethod<T>(IDictionary<string, IField<T>> parameters)
{
var param2 = parameters["param2"].Value;
}
While it is considered bad practice, you could use a Dictionary<string, Dynamic>
Dictionary<string, dynamic> dict = new Dictionary<string, dynamic>();
dict.Add("value1", "a");
dict.Add("value2", 2);
dict.Add("value3", 3);
int result = dict["value2"] + dict["value3"];
One way to manage what you're trying to do is to add access methods to IField that will allow you to get an object value and the type.
public interface IField
{
object GetValue { get; }
Type GetValueType();
}
I have a generic class that needs to limit an enum depending on the type defined:
public enum ConditionOperatorsString { None, Like, Equal }
public enum ConditionOperatorsDate { None, Equal, BeforeThan, AfterThan }
public class Condition<T>
{
public T Value { get; set; }
public ConditionOperatorsString Operator { get; set; }
public Condition(T Value, ConditionOperatorsString Operator)
{
this.Value = Value;
this.Operator = Operator;
}
}
Now the problem is that i want the Operator type be dependant on T so when:
Condition<string> CStr= new Condition<string>(string.Empty, ConditionOperatorsString.None)
Condition<DateTime> CStr= new Condition<DateTime>(DateTime.Now, ConditionOperatorsDate.None)
How do I define the class Condition for that? I thought of an interface but enums don't inherit from interfaces.
There's no good way to do what you're trying to do without having, in your constructor something like:
if (typeof(T) == typeof(string) &&
typeof(Operator) != typeof(ConditionOperatorsString))
{
throw new Exception("Invalid conditionoperators value);
}
That's really not very useful, since you have to know, ahead of time, all the different possibilities for T.
What you could do, is something like this:
public abstract class ComparableBase<T,K>
{
public T Value { get; protected set; }
public K ConditionOperator { get; protected set; }
// public abstract bool IsMatch(T other); // Is this required?
protected ComparableBase(T value, K op)
{
this.Value = value;
this.ConditionOperator = op;
}
}
public enum ComparableOperator { None, Equal, Less, Greater }
public enum LikeOrEqualOperator { None, Like, Equal }
public class ComparableCondition<T> : ComparableBase<T,ComparableOperator>
{
public ComparableCondition(T value, ComparableOperator op):base(value, op)
{
}
}
public class LikeOrEqualCondition<T> : ComparableBase<T, LikeOrEqualOperator>
{
public LikeOrEqualCondition(T value, LikeOrEqualOperator op):base(value, op)
{
}
}
then you can declare
var condition1 = new LikeOrEqualCondition<string>("hi", LikeOrEqualOperator.Equal);
Do you need to have an IsMatch? Or is this to display the selected filter, without actually implementing it.
If you do, things are a teensy bit more complicated...
Could the enum type just be another generic parameter e.g.
public enum ConditionOperatorsString { None, Like, Equal }
public enum ConditionOperatorsDate { None, Equal, BeforeThan, AfterThan }
public class Condition<T, TEnum>
{
public T Value { get; set; }
public TEnum Operator { get; set; }
public Condition(T Value, TEnum Operator)
{
this.Value = Value;
this.Operator = Operator;
}
}
Might need more info though, not 100% sure how this is meant to actually fit in with the code that will make use of it
You should include the enum type as a template parameter.
public class Condition<TValue, TOperator>
{
public TValue Value { get; private set; }
public TOperator Operator { get; private set; }
private Condition(TValue val, TOperator op)
{
Value = val;
Operator = op;
}
}
It would be nice to be able to add where TOperator : Enum, but I'm pretty sure the compiler doesn't allow that.
Thanks for the answers.
I wanted to avoid to have more than one class but apparently it cannot be done. Based on the last comment from silky i got to a similar sollution as nader.
Not the optimal one but it does the trick of restricting the enum, the con is that the client has to be aware that there are n classes:
public abstract class ConditionBase<T, E>
{
public T Value { get; set; }
public E Operator { get; set; }
protected ConditionBase(T Value, E Operator)
{
this.Value = Value;
this.Operator = Operator;
}
}
public enum ConditionOperatorsString { None, Like, Equal }
public class ConditionString : ConditionBase<string, ConditionOperatorsString>
{
public ConditionString(String Value, ConditionOperatorsString Operator) : base(Value, Operator) { }
}
public enum ConditionOperatorsDate { None, Like, BeforeThan, AfterThan }
public class ConditionDate : ConditionBase<DateTime?, ConditionOperatorsDate>
{
public ConditionDate(DateTime? Value, ConditionOperatorsDate Operator) : base(Value, Operator) { }
}
Client use:
ConditionString StrCond = new ConditionString(string.Empty, ConditionOperatorsString.None);
ConditionDate DateCond = new ConditionDate(DateTime.MinValue, ConditionOperatorsDate.None);
I wanted to be able to use from the client something like:
ConditionGeneric StrCond = new ConditionGeneric(string.Empty, ConditionOperatorsString.None);
ConditionGeneric DateCond = new ConditionGeneric(DateTime.MinValue, ConditionOperatorsDate.None);
ConditionGeneric InvalidStrCond = new ConditionGeneric(string.Empty, ConditionOperatorsDate.None);
ConditionGeneric InvalidDateCond = new ConditionGeneric(DateTime.MinValue, ConditionOperatorsString.None);
If you make your field
public ValueType Operator { get; set; }
It'll work, but I'm not sure if that's what you want ...
-- Edit
What are you trying to do, anyway? C# has operator overloading, so perhaps that could be of use, instead?