get;set; with DateTime to validate with .TryParse? - c#

I am attempting to move validation of input data into the get;set; of a class struct.
public void PlotFiles()
{
List<DTVitem.item> dataitems;
DTVitem.item i;
DateTime.TryParse("2012/01/01", out i.dt);
DateTime.TryParse("04:04:04", out i.t);
int.TryParse("455", out i.v);
dataitems.Add(i);
}
The struct is declared in a separate class (probably unnecessary):
public partial class DTVitem
{
public struct item
{
public DateTime dt;
public DateTime t;
public int v;
}
}
Every time I set DTVitem.item.dt, DTVitem.item.t, or DTVitem.item.v, I wish it to perform the relevant .TryParse() to validate the property contents.
However, when I attempt to use TryParse() as follows (attempting to wrap my head around this example from MSDN):
public partial class DTVitem
{
private DateTime _datevalue;
public string dt
{
get { return _datevalue; }
set { DateTime.TryParse(value, out _datevalue) ;}
}
}
I receive the error that _datevalue is a DateTime and cannot be converted to a string. The reason is obviously that the return path must return the type of dt in this instance (a string). However, I have attempted to massage this a few different ways, and am not able to hack it.
How do I achieve my goal of validating a string value as a DateTime when setting it as a property of an instance of the struct?
Is using set as I am attempting to the best way?
I can see that there is a lot of value in using get;set; for validation and would really like to understand it.
Thanks very much,
Matt
[edit]
Thanks to Jon Skeet below for pointing out the err of my ways.
Here's another thread on problems with mutable structs, and another speaking about instantiating a struct. Note structs are value types.
I believe the rest of what he was pointing out is sort of just agreeing that burying the struct way far away isn't necessary, and I should review why I'm doing it.
[solution]
I've taken into account some recommendations below and come up with the following:
public partial class DTVitem
{
private DateTime _dtvalue, _tvalue;
private int _vvalue;
public string dt
{
get { return _dtvalue.ToString(); }
set { DateTime.TryParse(value, out _dtvalue); }
}
public string t
{
get { return _tvalue.ToString(); }
set { DateTime.TryParse(value, out _tvalue); }
}
public string v
{
get { return _vvalue.ToString(); }
set { int.TryParse(value, out _vvalue); }
}
}
Inside my program class, I've instantiated and set with the following:
DTVitem item = new DTVitem();
item.dt = "2012/01/01";
item.t = "04:04:04";
item.v = "455";
So I opted not to use a struct, but a class; or really an instance of the class.

A property can only have one type. If you want the property to be of type string, then you can implement it this way:
public partial class DTVitem
{
private DateTime _datevalue;
public string dt
{
get { return _datevalue.ToString(); }
set { DateTime.TryParse(value, out _datevalue) ;}
}
}
However, using TryParse() will mean that the setter will not throw an exception if the DateTime is invalid. If you want it to do this, use DateTime.Parse() instead.

public partial class DTVitem
{
private DateTime _datevalue;
public string dt
{
get { return _datevalue.ToString(); }
set { DateTime.TryParse(value, out _datevalue) ;}
}
}

You're just missing a type convertion in the get. _datevalue is a DateTime but your property's a string.
get { return _datevalue.ToString(); } //or .toShortDateString() or ToShorttimeString()

The get;set; must have the same type. Your get returns a datetime when it expects a string, hence the error.
just use an explicit method bool setDate(String datestring) and put your code there. You can return a bool from the tryparse to let you know if it was successful.

Other (design mostly) issues aside, just getting to the problem of returning _datevalue as string, you can simply do something like:
public string dt
{
get { return _datevalue.ToString(); }
set { if(!DateTime.TryParse(value, out _datevalue)) /* Error recovery!! */ ;}
}
>>> You may also want to check the docs for DateTime.ToString() and see what format you want to get your string in when accessing the property.

Related

DataMember Property with Custom Get?

I'm going by this tutorial and trying to figure out how to have a DataMember without an auto property. Basically I have a field is a date time in epoch format and I want the property to be a DateTime so I'm trying to do the conversion in the property's get. I'm not sure how to format this exactly.
Since Code was requested please look at the following. :
// The date looks like this in the JSON
"someEpochDateTime": 1428785212000,
// I thought I could work around it using the following code, however
// I get a warning saying someEpochDateTime is never set.
[DataMember(Name = "someEpochDateTime")]
private long someEpochDateTime;
public DateTime test
{
get { return DateTimeConverter.FromUnixTime(someEpochDateTime); }
}
Using FromUnixTime
like this you can create datereturn property this will return date
[DataContract]
public class Mycontractclass
{
// Apply the DataMemberAttribute to the property.
[DataMember]
public DateTime datereturn
{
get
{
return this.dateCreated.HasValue
? this.dateCreated.Value
: DateTime.Now;
}
set { this.dateCreated = value; }
}
private DateTime? dateCreated = null;
}
Apparently my last edit actually works as a solution, I just get a compiler warning for some reason.
[DataMember(Name = "someEpochDateTime")]
private long someEpochDateTime;
public DateTime test
{
get { return DateTimeConverter.FromUnixTime(someEpochDateTime); }
}

Formatted string as datatype

I have a format for certain Ids and I'd rather have a custom datatype for them rather than store them as a string.
How is this done in C#?
Is this a good idea in the first place?
An example below should explain what I mean:
Id format (D for digit, C for alphabet char): CCDDDD
public ItemId id { get; set; }
...
public class ItemId {
// somehow declare the format here
}
You could wrap a class around your string ID which takes a input string as constructor parameter. This way you can also put methods in your class to provide extra functionality etc, and always have the formatting in one place. Simple example:
public class ItemId
{
private string _id;
public string ID
{
get { return _value; }
set
{
//do some formatting here
_id= value;
}
}
public ItemId(string id)
{
ID = id
}
public override string ToString()
{
//do some extra formatting here if needed
return Value;
}
}
Because you can only manipulate the real ID through the public setter, you can have your formatting and validation logic in one single place. Hope this helps you a bit. I think it's a good idea because a class ItemId is more meaningful then just a string, and also a lot easier to extend or change functionality in the future.
For example you can check the input with regex, and throw your own exception if input does not match your format. That gives you meaningful information at runtime. Also you can add xml comment to the public setter, so if you or anyone uses it, it's clear what the ID should look like.
You can also do it by implementing your extensions, which I would prefer than overriding ToString method.
For Example
public static class Extension
{
public static string MyFormat(this string str)
{
//do sth with your string
return str;
}
}
And you can use this extension like
string abc = "";
abc.MyFormat();

Class designing in C#

I'm learning C# and currently we're looking into OOP concepts. We've been given this question and I'm struggling to understand some parts of it.
The gist of the question is this.
Define a class named Operator.
That class should implement following methods.
IsPositive - Receives an integer type value and returns true if it
is positive, false otherwise.
IsDayOfWeek - Receives a date time value and a week day name (E.g.
Saturday) and returns true if the value represents the given week day
name, false otherwise.
GetWords - Receives a text containing words (say paragraphs) and
returns a single dimension string array with all words. An empty
string array if there is no word available in the text.
It should be able to derive from Operator class and then create objects from the derived class.
Developers are allowed to use these methods from derived class for a given type. In other words, 1st method could be used when type = ‘N’ (number), 2nd methods could be used when type is ‘D’ (date) and 3rd method could be used when type is ‘S’ (string) given. Hence, the type should be provided when instantiating the object and it should be available throughout the class operations.
I have sufficient knowledge to write the methods but what I don't understand is the part I have bold-ed. What does it mean by some method can be used when some type is given and the type should be provided when instantiating the object and it should be available throughout the class? Are they talking about Properties?
I have given it a go. Below is my code.
public class Operator
{
private int _n;
private DateTime _d;
private string _s;
public DataProcessor(int n, DateTime d, string s)
{
this.N = n;
this.D = d;
this.S = s;
}
public int N
{
set { _n = value; }
}
public DateTime D
{
set { _d = value; }
}
public string S
{
set { _s = value; }
}
public bool IsPositive()
{
//method code goes here
return false;
}
public bool IsDayOfWeek()
{
//method code goes here
return false;
}
}
I'm not sure if I'm going the right way. Can somebody please shed some light on this?
This is how I read it:
public class Operator
{
public char TypeChar { get; set; }
public Operator(char operatorType) { this.TypeChar = operatorType; }
public bool IsPositive(int N)
{
if (TypeChar != 'N')
throw new Exception("Cannot call this method for this type of Operator");
// method implementation code
}
// same for the other methods
}
public NumericOperator : Operator
{
public NumericOperator() : base('N') {}
}

Multiple accessors for same value in c#

I have simple scenario where I have AnotherTest value based on Test value. This works fine most of the time so that whenever I provide Test I am sure to get AnotherTest easily.
public sealed class Transaction {
public string Test { get;set; }
public string AnotherTest{
get {
int indexLiteryS = Test.IndexOf("S");
return Test.Substring(indexLiteryS, 4);
}
}
}
However I wanted to be able to also set AnotherTest value and be able to read it without having to provide Test value. Is this possible? So kinda 2 types of get based which way it was set. I know I could create 3rdTest but I have some methods that use AnotherTest and other fields and I would have to write overloads of that methods.
Edit:
I read some file supplied by bank. I cut it in pieces put some stuff in Test value and every other field (AnotherTest and similar) of the Transaction gets filled automatically.
However later on I would like to read Transaction from SQL that is already in nice format so I don't need to provide Test to get the rest of the fields. I would like to set those fields with set and then be able to use get without setting Test value.
Yes, like so:
public string Test { get; set; }
public string AnotherTest
{
get
{
if(_anotherTest != null || Test == null)
return _anotherTest;
int indexLiteryS = Test.IndexOf("S")
return Test.Substring(indexLiteryS, 4);
}
set { _anotherTest = value; }
}
private string _anotherTest;
That getter could also be expressed as
return (_anotherTest != null || Test == null)
? _anotherTest
: Test.Substring(Test.IndexOf("S"), 4);
I think this would do what you want it to do:
public sealed class Transaction {
public string Test { get;set; }
public string AnotherTest{
get {
if (_anotherTest != null)
{
return _anotherTest;
}
else
{
int indexLiteryS = Test.IndexOf("S");
return Test.Substring(indexLiteryS, 4);
}
}
set {
_anotherTest = value;
}
}
private string _anotherTest = null;
}
I would suggest turning the problem over.
It sounds like you're dealing with a big field and subfields within it. Instead, how about promoting those subfields to fields and constructing/deconstructing the big field when it's accessed.

Read property from the same class

In C# if I have this in a class:
public int SomeNumber
{
get { return 6; }
}
How can I read (get) that number from a function in the same class if the function receives a variable with the same name? Example:
public bool SomeFunction(int SomeNumber)
{
check if SomeNumber (the one passed to this function) == SomeNumber (the one from the public int)
}
You would simply invoke the property get in the method:
public void MyMethod()
{
var someNum = SomeNumber; // basically, var somNum = this.SomeNumber;
}
EDIT: To clarify with OP's edit:
public void MyMethod(int someNumber)
// Change the naming of your parameter so it doesnt clash with the property
{
if(someNumber == SomeNumber)
// Do Stuff
}
Same as if it were a field:
public void SomeOtherFunction()
{
var x = SomeNumber;
}
Although the other suggestions do work well (and adhere to easier to read/maintain code), they don't directly answer your question. Given a class
public class SomeClass
{
public int SomeNumber { get { return 6; } }
...
And a function with a parameter passed in
public void SomeMethod(int SomeNumber)
{
// Your code here...
You can access the passed in parameter and property like so:
if (SomeNumber > this.SomeNumber)
{
// Your results here
The distinction is that if you refer to just the variable name, it will use the variable from the same scope, i.e. the passed in variable. If you specify use "this." then you always get the class member.
Note: This does not work with Static classes, as there is no instance of the class. (Can't use "this.whatever") and you will be stuck. There are many coding Standards out there and some of them states that it is best practice to use the form "myVariable" for method parameters, "MyVariable" for property names, and _myVariable for property backing stores, to easily distinguish between them in your code.
public class FavoriteNumber
{
public int SomeNumber
{
get { return 6; }
}
Public int Twelve()
{
return SomeNumber*2;
}
}
Please run this code and you will get it.. Use this operator to refer the class level variale.
public void CheckNumber(int SomeNumber)
{
Console.WriteLine(SomeNumber);
Console.WriteLine(this.SomeNumber);
}

Categories