I have a struct like this (simplified for brevity):
public struct Period
{
public DateTime? Start { get; private set; }
public DateTime? End { get; private set; }
public bool IsMoment
{
get { return this.Start.HasValue && this.Start == this.End; }
}
public Period(DateTime? start, DateTime? end) : this()
{
this.Start = start;
this.End = end;
}
public override string ToString()
{
return this.IsMoment
? this.Start.Value.ToString("g")
: string.Format("{0:g} – {1:g}", this.Start, this.End);
}
}
Everything works fine, but ReSharper is showing a warning on this.Start.Value.ToString:
Possible 'System.InvalidOperationException'
If I copy the body of the IsMoment property into the condition, the warning goes away, but I'd like to be able to reuse the property. I can disable the ReSharper warning with a comment (which is what I have done for the moment), or by changing ToString to string.Format, but I have a handful of other places like this in my code and it got me thinking. I'd try to resolve this using code contracts, but unfortunately I don't have a whole lot of experience with code contracts and I'm not sure how it would look.
Is there anyway I use code contracts to indicate to ReSharper that if IsMoment is true, then Start is not null?
Do something like this in IsMoment:
contract.ensures(result == false || start <> null);
(That's not exactly right. I'm typing this on my phone.)
UPDATE:
The problem could be due to the possibility of multithreaded code changing the value of Start between the IsMoment test and the Start.Value evaluation.
It may be more correct to copy the value into a local variable that cannot be modified by other threads.
public override string ToString()
{
Period local = this;
return local.IsMoment
? local.Start.Value.ToString("g")
: string.Format("{0:g} – {1:g}", local.Start, local.End);
}
This looks like some unnecessary work, and it may look inefficient, but it more "correct". If your struct is small, though, this may actually be more efficient in many cases.
Have tried wrapping parens around it?
public override string ToString()
{
return (this.IsMoment
? this.Start.Value.ToString("g")
: string.Format("{0:g} – {1:g}", this.Start, this.End));
}
This might be a case for using Contract.Assume.
public override string ToString()
{
if (this.IsMoment) {
Contract.Assume(this.Start.HasValue);
return this.Start.Value.ToString("g");
}
else
return string.Format("{0:g} – {1:g}", this.Start, this.End));
}
Related
In the beginning, there was code:
public abstract class A
{
private string _someValue;
public string SomeValue
{
get
{
if (_someValue == null)
_someValue = GetValue();
return _someValue;
}
}
protected virtual string GetValue() { /* logic */ }
}
public class B : A
{
protected override string GetValue()
{
return base.GetValue() + GetMoreValue();
}
private string GetMoreValue() { /* logic */ }
}
And the code said, "Let there be bugs!" and there were bugs.
Seriously now.
I have an instance of B, and when I get SomeValue, I get the same SomeValue of A, without the MoreValue.
The even weirder part came when I put a breakpoint on SomeValue's Get method:
It turns out that _someValue gets its value before the Get method is ever called.
Something is very wrong here.
UPDATE:
Thanks for the comments! Shortened code, and added forgotten return type in B method.
It turns out I was making a stupid mistake.
(I would delete the question, but I figured others can learn from my blooper.)
I had a watch on SomeValue.
The result? Get SomeValue was called the moment I started debugging.
(Which is a little weird, because I had a breakpoint on the Get method which didn't activate. For some reason, watches don't trigger breakpoints.)
*(As for the wrong value, that had nothing to do with inheritance -
GetMoreValue simply happened to return an empty string.)
I have class named "config" that have private string variable named "param".
I need to get from "config" class "param" variable sometimes as int type sometimes as bool type or string.
As I understand I need create 3 properties in config class,each property have to convert type, as follow:
The first property converts string to int, the second converts string to bool, the third property gets me the string value.
The class should look something like this:
class Config
{
private string param;
public int ParamAsInt
{
get
{
return int.Parse(param);
}
}
public bool ParamAsBool
{
get
{
return bool.Parse(param);
}
}
public string ParamAsString
{
get
{
return param;
}
}
}
But I don't know how can those properties be used in accordance to the variable type that I want to get out of class.
This code won't compile - int and such are reserved keywords and cannot be used as identifiers. You can either try naming your properties something like Int32Value, StringValue, etc., or try this:
public static implicit operator bool (Config config)
{
return bool.Parse(config.param);
}
public static implicit operator int (Config config)
{
return int.Parse(config.param);
}
This will allow for much cleaner code:
Config c = GetConfig("foo");
var isFeatureEnabled = false || c;
var spacing = 23 + GetConfig("bar");
You forgot to give your properties names. How would you expect to reference them? Something like this:
class Config
{
private string param;
public int ParamAsInt
{
get
{
return int.Parse(param);
}
}
public bool ParamAsBool
{
get
{
return bool.Parse(param);
}
}
public string ParamAsString
{
get
{
return param;
}
}
}
Note that I also fixed the casing in your calls to .Parse(). C# is case-sensitive. I also replaced the call to bool.TryParse() with bool.Parse(). The former (when used correctly, which this wasn't because it was missing a parameter) will only tell you if it is a bool, it won't tell you what value the bool actually has. (For example, bool.TryParse('false' out someBool) will return true.)
Of course, this code is a bit dangerous. You'll want to start with some more defensive programming to check those values. Basically, look up TryParse() and how to use it correctly. Something like this, for example:
public int ParamAsInt
{
get
{
var tmp = default(int);
if (int.TryParse(param, out tmp))
return tmp;
else
// do something else? throw a specific exception?
}
}
Additionally, what is the purpose of this code? It seems like a very rushed and poor design. For any given value of param (how is that even being set, by the way?) this just sort of randomly tries to expose typed properties for it. If you guess the correct one, you're still left with others that will throw exceptions. Surely there's a much cleaner way to accomplish what you're trying to do. So what are you trying to do?
I was recently talking with a buddy about return values taking only a single meaning. At my previous job, we worked with C++ and had typedef'ed wBOOL so that a 0 was wFALSE, and 1 was wTRUE. The architect said that we can also return 2, 3, 4... for more information, which I think is a horrible idea. If we expect wTRUE = 1 and wFALSE = 0 and wBOOL = {wTRUE, wFALSE}, returning anything else should be avoided... now, on to today's C#.
I recently reviewed a piece of code where there were a collection of functions that determined if there was an error and returned the string back to the user:
private bool IsTestReady(out string errorMessage)
{
bool isReady = true;
errorMessage = string.Empty;
if(FailureCondition1)
{
isReady = false;
errorMessage = FailureMessage1;
}
else if(FailureCondition2)
{
isReady = false;
errorMessage = FailureMessage2;
}
//... other conditions
return isReady;
}
Then, to use these functions...
private enum Tests
{ TestA, TestB, TestC }
private void UpdateUI()
{
string error = string.Empty;
bool isTestReady;
switch(this.runningTest) // which test are we running (TestA, TestB, or TestC)
{
case Tests.TestA:
isTestReady = IsTestAReady(error);
break;
case Tests.TestB:
isTestReady = IsTestBReady(error);
break;
case Tests.TestC:
isTestReady = IsTestCReady(error);
break;
}
runTestButton.Enabled = isTestReady;
runTestLabel.Text = error;
}
I thought to separate these out into two methods:
private string GetTestAErrorMessage()
{
//same as IsTestReady, but only returns the error string, no boolean stuffs
}
private bool IsTestAReady
{
get{ return string.IsNullOrEmpty(GetTestAErrorMessage()); }
}
Does this violate the principal of not having a return value mean more than one thing? For instance, in this case, if there error message IsNullOrEmpty, then there is no error. I think that this does not violate that principal; my co-worked does. To me, it's no different than this:
class Person
{
public int Height {get;}
public bool IsTall() { return Height > 10; }
}
Any thoughts or suggestions on a different approach to this issue? I think the out parameter is the worst of the solutions.
The return value and the error message are technically not bound together. You could have a developer come along at a later time and add a new failure condition to IsTestReady, and that failure condition may not set an error message. Or, perhaps there is a message, but it doesn't exactly represent a failure (like, perhaps a warning or something), so the error message parameter may get set, but the return value is true.
An exception doesn't really work in this case either, for the exact reason that StriplingWarrior wrote in his comment - exceptions should be used for non-normal operational states, and a non-ready test is a normal state.
One solution might be to remove the error message parameter and have the IsTestReady function return a class:
public class TestReadyResult {
public bool IsReady { get; set; }
public string Error { get; set; }
}
There is just one property to check - TestReadyResult.IsReady - for test state, and if necessary, the Error property can be used for non-ready states. There is no extra parameter to manage for the function call, either.
I'm not a big fan of having the null or empty return value indicate that nothing is wrong. A better comparison than the one you gave is:
class Person
{
public int Height {get;}
public bool IsBorn() { return Height > 0; }
}
In .NET, it is common practice to use the "bool return with out parameter" pattern you see in your original method (see the various TryParse methods, for example). However, if you prefer, another solution would be to create a TestReadyCheck class with both the boolean and the string as properties. I've done something similar with the following class, and been quite happy with it.
public class RequestFilterResult
{
public static readonly RequestFilterResult Allow = new RequestFilterResult(true, null);
public static RequestFilterResult Deny(string reason) { return new RequestFilterResult(false, reason); }
protected RequestFilterResult(bool allowRequest, string denialReason)
{
AllowRequest = allowRequest;
DenialReason = denialReason;
}
public bool AllowRequest { get; private set; }
public string DenialReason { get; private set; }
}
This allows for the following usage:
public RequestFilterResult Filter(...)
{
if (FailureCondition1) return RequestFilterResult.Deny(FailureMessage1);
if (FailureCondition2) return RequestFilterResult.Deny(FailureMessage2);
return RequestFilterResult.Allow();
}
It's concise, while enforcing that failure results provide a failure message, and success results don't.
On a side note, the structure of your switch statement feels like a code smell to me. You may want to consider ways to leverage polymorphism. Maybe make each test have its own class, with an IsTestReady method on it?
I would use exceptions to convey information about failure states, rather than relying on the caller to know how to use an error message field (even though it's private).
I want to serialize a nullable bool simply by converting it to a string
public static string SerializeNullableBoolean(bool? b)
{
if (b == null)
{
return "null or -1 or .."; // What to return here?
}
else
{
return b.ToString();
}
}
What is the most appropriate string to serialize the null-value as?
Since bool.ToString() returns "True" or "False", I would go with "Null". I would also rewrite this as:
return b.HasValue ? b.ToString() : "Null";
Edit: I take that back. bool?.ToString() returns empty string, so I would decide based on what's more convenient. If a person needs to read the output then "Null" is a better choice; if it only needs to be used in code then empty string is fine. If you go with empty string it is as simple as:
return b.ToString();
Why not:
b.ToString()
If b is null, then it returns an empty string. Since that's what the framework returns, I would use it to be consistent. This is also what XmlSerializer uses for nullable scalars.
If you're returning True/False for real bool values, you should return Null for symmetry's sake in case b is null.
Be consistent.
b.ToString()
returns the strings 'true' or 'false'. Thus if you return -1 it will be less consistent if you actually read the serialized files. The deserialization code will also become more "ugly" and less readable.
I would choose to serialize it to either the string 'unset' (or something along those lines) or the string 'null'. Unless you have really strict space requirements or really huge datasets to serialize the extra characters shouldn't really matter.
I would choose an empty string to represent the null-value.
If you are using the built in XmlSerializer you can also do the following to serialize the value (and prevent a lot of ugly custom serialization code):
[Serializable]
public class Foo
{
[XmlIgnore]
public bool? Bar { get; set; }
[XmlAttribute("Bar")]
[EditorBrowsable(EditorBrowsableState.Never)]
public string xmlBar
{
get { return Bar.ToString(); }
set
{
if (string.IsNullOrEmpty(value)) Bar = null;
else Bar = bool.Parse(value);
}
}
}
Personally I wouldn't use any of the above but simply use ShouldSerialize interface.
For example,
[XmlElement("SomeBoolean ", Namespace = "SomeNamespace")]
public bool? SomeBoolean { get; set; }
public bool ShouldSerializeSomeBoolean() { return SomeBoolean.HasValue; }
So I've got a whole bunch of options, every different page/tab can have their own local options. We'll have maybe 10-15 pages tabs open tops. I need to implement a way to show the global defaults, weather the all the tabs have consistent values. I'm working on the model/viewmodel portion of a WPF app.
I'd love to find a way that is more elegant since I'm having to cut and past roughly the same code 20+ times and just change property names. Maybe this is the problem Dynamics solve, but right now this feels both wrong and painful.
Here is an example of my current solution:
public class Foo
{
private bool fooVar1;
private bool fooVar2;
//lots of these
private decimal fooVar23;
public Foo()
{
}
public bool FooVar1
{
get;
set;
}
//you get the picture...
}
public class FooMonitor
{
private Foo defaultFoo;
private List<Foo> allFoos;
public FooMonitor(Foo DefaultFoo)
{
defaultFoo = DefaultFoo;
}
public void AddFoo(Foo newFoo)
{
allFoos.Add(newFoo);
}
public void AddFoo(Foo oldFoo)
{
allFoos.Remove(oldFoo);
}
public bool IsFooVar1Consistent
{
get
{
Foo[] tempFoos = allFoos.ToArray();
foreach (Foo tempFoo in tempFoos)
{
if (tempFoo.FooVar1 != defaultFoo.FooVar1) return false;
}
return true;
}
}
}
Or am I approaching this problem entirely incorrectly.
As I'm writing this question (After about 2000 lines of code) I'm thinking of how I read that WPF itself implements Dictionary look ups that crawl up to the parent to see if a Property is present and what the value should be.
Well, for a start you are defining both backing fields which will never be used and automatic properties. This is enough for a simple bool property:
public bool FooVar1 { get; set; }
No need for the private field. This greatly reduces the number of lines in your example.
I'd love to find a way that is more
elegant since I'm having to cut and
past roughly the same code 20+ times
and just change property names.
Code generators exist for exactly this purpose. But if you don't want to go that route, you can shorten your code to this:
return allFoos.All(foo => foo.FooVar1 == defaultFoo.FooVar1);
I'm not quite sure what the question is, but if you're looking for some way to unify the IsFoorVarXConsistent code, you could do it using reflection or by passing in an expression:
public bool IsConsistent(Func<Foo, bool> property)
{
foreach (Foo tempFoo in allFoos)
{
if (property(tempFoo) != property(defaultFoo))
return false;
}
return true;
}
Called like this:
bool is1Consistent = IsConsistent(f => f.FooVar1);
As shown this will only work for boolean properties. To extend it to other types, we can make it generic in the property type. However, in this case we cannot use != to test for inequality because not all types define a != operator. Instead we can use the .Equals method and the ! operator:
public bool IsConsistent<T>(Func<Foo, T> property)
where T : struct
{
foreach (Foo tempFoo in allFoos)
{
if (!property(tempFoo).Equals(property(defaultFoo)))
return false;
}
return true;
}
The where T : struct clause restricts this to value types like int, bool and decimal. In particular it will not work on strings. Removing the where constraint allows it to work on strings and other reference types, but creates the possibility of property(tempFoo) being null, which would cause a NullReferenceException when we called .Equals on it. So if you remove the value types constraint then you will need to add error handling for this scenario.