Dependent boolean properties - c#

Lets say I have an object with two boolean properties:
public bool AdvancedMode{ get; set; }
public bool DumpDiagnostics{ get; set; }
The domain rules state that DumpDiagnostics is not allowed unless AdvancedMode is also true. So throughout the code you might see statements like this:
if( options.AdvancedMode && options.DumpDiagnostics ){ ... }
The problem with this is that it's easy to forget to add the check forAdvancedMode and accidentally check only for DumpDiagnostics.
if( options.DumpDiagnostics ) // Oh no!
So there are two solutions that I can think of:
Option 1: DumpDiagnostics only returns true when AdvancedMode is true.
public bool DumpDiagnostics
{
get{ return AdvancedMode && _dumpDiagnostics; }
set{ _dumpDiagnostics = value; }
}
Option 2: New property that reflects the condition I'm looking for
public bool CanDumpDiagnostics{ get{ return AdvancedMode && DumpDiagnostics; } }
Question: Which is better?
Option #1 seems pretty easy and less prone to error. There's always one authority on whether diagnostics can be dumped. But, it does change the set -> get semantics where you can assign DumpDiagnostics = true, followed by if( DumpDiagnostics ) where it returns false.
Option #2 is good because it isolates the logic and makes it clear what the purpose is. The biggest drawback I see with it is that it's still easy to just check for DumpDiagnostics instead of using the new CanDumpDiagnostics property.
p.s. I know it's an awkward title but couldn't come up with something more precise, feel free to modify.

Alternately, pick option 3... turn the two booleans into an enum:
public enum Mode
{
Normal,
Advanced,
AdvancedWithDiagnostics
}
(with names that are more appropriate for what you are doing)
Addendum:
If you want to go really "advanced", you can even use the following:
public enum Mode
{
Normal = 0,
Advanced = 1,
AdvancedWithDiagnostics = 3
}
And use the following properties (again, pick better naming than mine!):
public Mode SelectedMode { get; set; }
public bool AdvancedMode { get { return (SelectedMode & 1) != 0; } }
public bool DumpDiagnostics { get { return (SelectedMode & 2) != 0; } }

Option 2 makes more sense to me. I don't like properties which can be set but don't "take hold". I was going to suggest throwing an exception in the setter, but then remembered that you'd also have to throw an exception in the setter for AdvancedMode in case that was reset to false.
I'd rename DumpDiagnostics to something like DiagnosticDumpRequested to make it clearer that it doesn't guarantee it'll be honoured.

What are the domain rules of the getting and setting the states? In other words, it seems to me like the "set" function for DumpDiagnostics should also set the AdvancedMode. If this is true, then just go with option 1 and you'll only need to check that DumpDiagnostics is set in the rest of your code.

Option 1 is misleading. DumpDiagnostics should not be equal to AdvancedMode && DumpDiagnostics. I would go with option 2

Related

Check if an enum flag contains a certain flag value

In C# (using Unity working on a game) I have an enum with the [Flag] attribute. I have instantiated it twice. I would like a way to compare the two enums. Specifically if enum A (which will have multiple flags) contains a flag from enum B (which will only ever be assigned a single flag).
I am not trying to compare a single instantiated enum to a single flag (this has been answered multiple times).
I suspect I could do this by dumping values with GetValue and comparing those values on a foreach loop, but it seems like there should be a more direct way to compare.
public enum AbilityType
{
None = 0,
Pierce = 1<<1,
Blunt = 1<<2,
Slash = 1<<3,
Water = 1<<4,
// etc.
};
public class Ability : MonoBehaviour
{
public AbilityType abilityType;
}
public class AbilitiedObject : StatisticalObject
{
public AbilityType resistances;
protected override void Awake()
{
base.Awake();
resistances = AbilityType.Pierce | AbilityType.Water;
}
public void TakeDamage(int damageAmount, AbilityType abilityType)
{
if( ) // Check if resistances contains abilityType's flag here
{
print("You are resistance to this damage type");
}
else
{
// Player takes damage
}
}
}
I'd like the above code to check if resistances contains the flag from abilityType. In the example above, the attack in question will pass it's abilityType in. If that type is water or pierce, it should print the resistance statement. If it's another type, it should deal damage as normal.
What you want is to abuse, as stated in the comments and other answers, is the bitwise & operator to compare as enums are (by default) based on the int type. However since .NET 4.0 there has been the addition of Enum.HasFlag extension method that does exactly this and increases readability.
// These two are semantically equal
if (resistance.HasFlag(abilityType))
{
print("You are resistance to this damage type");
}
if ((resistance & abilityType) != 0)
{
print("You are resistance to this damage type");
}
Behind the scenes of this is explained by numerous others. Can personally recommend Alan Zucconi's Enum, Flags and bitwise operators
Short version is that the bitwise AND (&) operator gives a result of where two values "match" in the sense that they're both active, bit by bit. One way to think of it is as a selective filter. To check if a value A of unknown flag set contains a specific flag B, you use the filter which only allows flag B to pass through and check if anything got through, where anything is represented as anything else than zero. The filter is simply the same as the flag you wish to look for. Therefore the expression becomes (A & B) != 0. Parentheses to force override order of operations since != has higher precedence than &.
Here's what you need:
if ((resistances & abilityType) != 0)
{
print("You are resistance to this damage type");
}
...

C# property set if

Can I make a property in c# class that has no field, but I still can check the value and set it only if match?
I mean something like this:
public int Num
{
get;
set if value > 0 && value < 100;
}
I know that I can do this:
private int num;
public int Num
{
get
{
return num;
}
set
{
if (value > 0 && value < 100)
num = value;
}
}
But I want to do it without using a field, and just using property.
Is it possible?
To be clear: btw; it's not that the property won't be set to that value, it's just a different way to look at your question.
You can use attributes, but you'll need a way to validate them. For instance; the Range attribute:
[Range(0,100, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Num {get; set;}
So, this is typically used in MVC or EF like applications where the attributes are being checked by that particular framework.
There is some more info about that subject here: https://msdn.microsoft.com/en-us/library/cc668215(v=vs.110).aspx
It can also work in MVVM WPF applications, but again, you'll need a framework for that.
btw; it's not that the property won't be set to that value, it's just a different way to look at your question.
So if your use case is actually how to restrict and easily apply some business rules on a view or data-model, this is an accepted method. If you keep it to your original question can I do a conditional set without an if and a field?, the answer is no.
Some more attributes can be found here.
I think the answer is no. You may want to see this one and this one to know why.
Fields are ordinary member variables or member instances of a class. Properties are an abstraction to get and set their values.
by doing the first block, you just break shorthand that already defined in C# and if you want to implement that idea, I think #Stefan proposed a good one.

Objects with many value checks c#

I want to see your ideas on a efficient way to check values of a newly serialized object.
Example I have an xml document I have serialized into an object, now I want to do value checks. First and most basic idea I can think of is to use nested if statments and checks each property, could be from one value checking that it has he correct url format, to checking another proprieties value that is a date but making sue it is in the correct range etc.
So my question is how would people do checks on all values in an object? Type checks are not important as this is already taken care of it is more to do with the value itself. It needs to be for quite large objects this is why I did not really want to use nested if statements.
Edit:
I want to achieve complete value validation on all properties in a given object.
I want to check the value it self not that it is null. I want to check the value for specific things if i have, an object with many properties one is of type string and named homepage.
I want to be able to check that the string in the in the correct URL format if not fail. This is just one example in the same object I could check that a date is in a given range if any are not I will return false or some form of fail.
I am using c# .net 4.
Try to use Fluent Validation, it is separation of concerns and configure validation out of your object
public class Validator<T>
{
List<Func<T,bool>> _verifiers = new List<Func<T, bool>>();
public void AddPropertyValidator(Func<T, bool> propValidator)
{
_verifiers.Add(propValidator);
}
public bool IsValid(T objectToValidate)
{
try {
return _verifiers.All(pv => pv(objectToValidate));
} catch(Exception) {
return false;
}
}
}
class ExampleObject {
public string Name {get; set;}
public int BirthYear { get;set;}
}
public static void Main(string[] args)
{
var validator = new Validator<ExampleObject>();
validator.AddPropertyValidator(o => !string.IsNullOrEmpty(o.Name));
validator.AddPropertyValidator(o => o.BirthYear > 1900 && o.BirthYear < DateTime.Now.Year );
validator.AddPropertyValidator(o => o.Name.Length > 3);
validator.Validate(new ExampleObject());
}
I suggest using Automapper with a ValueResolver. You can deserialize the XML into an object in a very elegant way using autommaper and check if the values you get are valid with a ValueResolver.
You can use a base ValueResolver that check for Nulls or invalid casts, and some CustomResolver's that check if the Values you get are correct.
It might not be exacly what you are looking for, but I think it's an elegant way to do it.
Check this out here: http://dannydouglass.com/2010/11/06/simplify-using-xml-data-with-automapper-and-linqtoxml
In functional languages, such as Haskell, your problem could be solved with the Maybe-monad:
The Maybe monad embodies the strategy of combining a chain of
computations that may each return Nothing by ending the chain early if
any step produces Nothing as output. It is useful when a computation
entails a sequence of steps that depend on one another, and in which
some steps may fail to return a value.
Replace Nothing with null, and the same thing applies for C#.
There are several ways to try and solve the problem, none of them are particularly pretty. If you want a runtime-validation that something is not null, you could use an AOP framework to inject null-checking code into your type. Otherwise you would really have to end up doing nested if checks for null, which is not only ugly, it will probably violate the Law of Demeter.
As a compromise, you could use a Maybe-monad like set of extension methods, which would allow you to query the object, and choose what to do in case one of the properties is null.
Have a look at this article by Dmitri Nesteruk: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
Hope that helps.
I assume your question is: How do I efficiently check whether my object is valid?
If so, it does not matter that your object was just deserialized from some text source. If your question regards checking the object while deserializing to quickly stop deserializing if an error is found, that is another issue and you should update your question.
Validating an object efficiently is not often discussed when it comes to C# and administrative tools. The reason is that it is very quick no matter how you do it. It is more common to discuss how to do the checks in a manner that is easy to read and easily maintained.
Since your question is about efficiency, here are some ideas:
If you have a huge number of objects to be checked and performance is of key importance, you might want to change your objects into arrays of data so that they can be checked in a consistent manner. Example:
Instead of having MyObject[] MyObjects where MyObject has a lot of properties, break out each property and put them into an array like this:
int[] MyFirstProperties
float[] MySecondProperties
This way, the loop that traverses the list and checks the values, can be as quick as possible and you will not have many cache misses in the CPU cache, since you loop forward in the memory. Just be sure to use regular arrays or lists that are not implemented as linked lists, since that is likely to generate a lot of cache misses.
If you do not want to break up your objects into arrays of properties, it seems that top speed is not of interest but almost top speed. Then, your best bet is to keep your objects in a serial array and do:
.
bool wasOk = true;
foreach (MyObject obj in MyObjects)
{
if (obj.MyFirstProperty == someBadValue)
{
wasOk = false;
break;
}
if (obj.MySecondProperty == someOtherBadValue)
{
wasOk = false;
break;
}
}
This checks whether all your objects' properties are ok. I am not sure what your case really is but I think you get the point. Speed is already great when it comes to just checking properties of an object.
If you do string compares, make sure that you use x = y where possible, instead of using more sophisticated string compares, since x = y has a few quick opt outs, like if any of them is null, return, if the memory address is the same, the strings are equal and a few more clever things if I remember correctly. For any Java guy reading this, do not do this in Java!!! It will work sometimes but not always.
If I did not answer your question, you need to improve your question.
I'm not certain I understand the depth of your question but, wouldn't you just do somthing like this,
public SomeClass
{
private const string UrlValidatorRegex = "http://...
private const DateTime MinValidSomeDate = ...
private const DateTime MaxValidSomeDate = ...
public string SomeUrl { get; set; }
public DateTime SomeDate { get; set; }
...
private ValidationResult ValidateProperties()
{
var urlValidator = new RegEx(urlValidatorRegex);
if (!urlValidator.IsMatch(this.Someurl))
{
return new ValidationResult
{
IsValid = false,
Message = "SomeUrl format invalid."
};
}
if (this.SomeDate < MinValidSomeDate
|| this.SomeDate > MinValidSomeDate)
{
return new ValidationResult
{
IsValid = false,
Message = "SomeDate outside permitted bounds."
};
}
...
// Check other fields and properties here, return false on failure.
...
return new ValidationResult
{
IsValid = true,
};
}
...
private struct ValidationResult
{
public bool IsValid;
public string Message;
}
}
The exact valdiation code would vary depending on how you would like your class to work, no? Consider a property of a familar type,
public string SomeString { get; set; }
What are the valid values for this property. Both null and string.Empty may or may not be valid depending on the Class adorned with the property. There may be maximal length that should be allowed but, these details would vary by implementation.
If any suggested answer is more complicated than code above without offering an increase in performance or functionality, can it be more efficient?
Is your question actually, how can I check the values on an object without having to write much code?

How do I ensure the value of property for others that are dependent upon it?

I have a property like so:
private Decimal _payout;
public Decimal PayoutValue
{
get { return _payout; }
set
{
_payout = value;
//second part of following conditional is an enum
if (Math.Abs(value) > 1 && this.PayoutType == CutType.Percent)
{
_payout /= 100;
}
}
}
As you can see, it is dependent upon the value of PayoutType, which is just a simple enum property:
public CutType PayoutType { get; set; }
My problem is that PayoutType doesn't seem to get set before PayoutValue is set, so the conditional below is never true. How do I force the PayoutType to be set before PayoutValue is evaluated?
Thanks.
UPDATE Thanks for your answers guys. I guess I should have mentioned that most of the time this object is bound via DataContexts or from an Http.Post from my client side (MVC project), so I don't really have any constructors. Is there any other way, or should I start getting creative with my programming?
How do I force the PayoutType to be set before PayoutValue is evaluated?
Put it in the constructor. That's the only way to enforce this rule.
That being said, I would recommend against this, at least in your implementation above. Your current property implementation will be very, very confusing to users. People tend to expect that setting a property, then immediately fetching it will provide the same value.
In your case, though:
decimal value = 45.3;
myObject.PayoutValue = value; // Set this
if (myObject.PayoutValue != value)
{
// This would normally be a very unexpected case! In your example, it will always be true!
}
It would be much better to potentially use two properties, or a method (ie: SetPayoutValue(decimal value)) to clue the user into the fact that it's not acting like a simple property.
How about this ?
get
{
if (Math.Abs(value) > 1 && this.PayoutType == CutType.Percent)
{
return _payout /100;
}
return _payout;
}
set{_payout = value;}
So that you do not change the value that was set.
All "required" properties should be in the constructor of your class.

Getter/Setter problem in C#

I am doing
static bool isWorking
{
get { return _isWorking; }
set {
myform.treeView1.Enabled = !value;
_isWorking = value;
}
}
and stepping through the debugger shows it stops at the first set line.
After trying this line instead
set { myform.treeView1.Enabled = !(_isWorking = value); }
I see that isWorking is set but myform.treeView1.Enabled is not. Whats going on?
What do you mean by "the debugger shows it stops"? Is it possibly that myform is null, or myform.treeView1 is null?
I can't remember the exact evaluation order in this case, but it could explain the symptoms you're describing. Knowing why the debugger "stops" is crucial though. Another possibility is that you're trying to access the UI from a non-UI thread, which would prevent the assignment to Enabled from working properly.
Oh, and please don't use your second version - assignment as a side-effect is very, very rarely a good idea. The only idiomatic use I know is when looping with IO:
string line;
while ( (line = reader.ReadLine()) != null)
and I only consider that acceptable because it's reasonably common. In this case it really looks like you could mean "==" instead of "=".
Because (_isWorking = value) returns always true. If you would write:
myform.treeView1.Enabled = !(_isWorking == value);
It works like: if isWorking is equal to value then Disable treeView. But in you case - no

Categories