Multiple accessors for same value in c# - 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.

Related

Byte array Properties C#

I have an object like this:
public class CustomObject{
public byte[] FieldA {private get; set;}
public IPAddreess FieldB {private get; set;}
}
FieldA is the byte rappresentation of FieldB.
I create this object from two sources of data.
One from a binary file where i need to be fast, then i prefer to set only the FieldA. The other one is in an application where i retrieve the data only in "FieldB format".
I want a function like this:
public IPAddress GetField(){
if (FieldB != null)
return FieldB;
FieldB = new IPAddress(FieldA);
return FieldB;
}
To simplify i used an IPAddress conversion, but usually i have more complex operations to do.
Is this the correct way to do this? Or there is some other method that can simplify this one? I'm using .NET CORE Thank you in advance
You can do that in FieldB's getter, without explicitly writing a get-method:
private IPAddreess _fieldB;
public IPAddreess FieldB
{
get
{
if (_fieldB == null)
{
_fieldB = new IPAddress(FieldA);
}
return _fieldB;
}
set
{
_fieldB = value;
}
}
This code uses a private backing field _fieldB for storing the property's value. Upon retrieving the property, it'll either return the value already stored in the field, or assign it based on FieldA's contents and then return it.

Why keep two variables for one content in C# UWP?

In C#, I notice that many coders do something like the following:
class X
{
private int test_;
public int test
{
get { return test_; }
set { if (test_ != value) test_ = value; }
}
}
My question is why keep a private, and a public variable for the same content?
Why did we not do this instead?
class X
{
public int test
{
get; set;
}
}
I mean, we are changing the private variable within anyway. What is the point of not using a single public variable instead?
The code:
class X
{
public int test
{
get; set;
}
}
...is a direct equivalent for this:
class X
{
private int test_;
public int test
{
get { return test_; }
set { test_ = value; }
}
}
The first example is an auto-implemented property. The C# compiler automatically produces the second example when you compile.
Now, the code you presented first though had this line:
set { if (test_ != value) test_ = value; }
You'll notice that it's doing something different to the auto-property equivalent code. And that's where the difference lies in these two approaches.
When you use a backing field for your properties you can introduce specific rules that you need your code to follow.
For example, you might want to set the audio volume on a music app, so your code might be like this:
public class Music
{
private int _volume = 7;
public int Volume
{
get { return _volume; }
set
{
if (value >= 0 && value <= 10)
{
_volume = value;
}
}
}
}
It is common to have a private field variable when your property contains logic like this.
These are not two variables. One is a field and other one is a property. A property is optional getter and setter methods in disguise.
Your proposal of the solution is in fact part of the language, called auto-implemented properties:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties

Is there anyway to reconstruct an object inside itself?

I have a simple class that is intended for options of an winforms application. There should be a method that reset options to their default values. I know I can add a separate method to take care of this, but the code will be huge (If I add more options to the class) :
public SensorOptions()
{
ShowLabelMax = ShowLabelMin = ShowLabelAvr = ShowReceivedTextBox = true;
ChartMaxValue = 140;
ChartMinValue = -40;
ShowChartMinValue = ShowChartMaxValue = ShowChartAvrValue = ShowChartAvrLine = true;
LogFolder = Environment.SpecialFolder.MyDocuments.ToString();
LoggingEnabled = true;
}
public void ResetOptions()
{
this = new SensorOptions(); //can not do. 'this' is read-only
}
I mean I can copy/paste the code from constructor into ResetOptions() method. But is there any smarter ways to achieve this?
You cannot assign this because you may have references to this instance of your class in your program. If you could re-construct the object by re-assigning this, it would mean that all references to the old instance of the class become invalid.
No matter how many options you have in your class, you initialize each of them one or the other way (because you mention default value in your question - so you need to assign that default value somewhere at least once, probably in the constructor). Therefore, the solution to your problem is simple - move all initializers to the separate method and call it in the constructor, and then also call it every time you need to reset your options to their default values.
If any of your options are not assigned a default value explicitly, and use system default and you don't want to write option=default(optionType) for each option, you can use reflection to enumerate all fields/properties in that class and assign default values to them, like this:
public static object GetDefault(Type type)
{
if(type.IsValueType) return Activator.CreateInstance(type);
return null;
}
foreach(var field in this.GetType().GetFields())
field.SetValue(this, GetDefault(field.FieldType));
foreach(var prop in this.GetType().GetProperties())
prop.SetValue(this, GetDefault(prop.PropertyType));
Move all of the code from the constructor into the ResetOptions method, then in your constructor call the ResetOptions method. Your initialisiation code is only in one place then.
You have very simple architecture for your situation. In my opinion it would be better to apply a trick for this:
you have class for holding all your options (pseudo code):
class AllOptionsBackstage
{
public bool ShowLabelMax { get; set; }
public bool ShowLabelMin { get; set; }
public bool ShowLabelAvr { get; set; }
public AllOptionsBackstage()
{
// apply default values here
}
}
.....
class MyOptions
{
private AllOptionsBackstage _options;
public MyOptions()
{
Reset();
}
public bool ShowLabelMax
{
get{ return _options.ShowLabelMax; }
set{ _options.ShowLabelMax = value; }
}
public bool ShowLabelMin
{
get{return _options.ShowLabelMin;}
set{_options.ShowLabelMin=value; }
}
public bool ShowLabelAvr
{
get{ return _options.ShowLabelAvr;}
set{ _options.ShowLabelAvr = value; }
}
public void Reset()
{
_options = new AllOptionsBackstage(); // will reset all your options to default
}
}

Put an array in to a column

I want to use EF code first to create a column into a table Task, which is an array. How?
public class Task
{
// my presumption code
public string[] Attempts { get; set; }
The Attempts has
AttemptsMetadata---maybe string
Time ---DataTime
Answered ---bool
Create a property to be used in the code (and mark as ignore) and other property to be used in code.
EDITED
public class Task
{
[Ignore]
public string[] Attempts { get; set; }
public string AttemptsMetadata
{
get
{
return Attempts != null && Attempts.Any()
? Attempts.Aggregate((ac, i) => ";" + ac + i).Substring(1)
: null;
}
set { Attempts = value.Split(';'); }
}
}
PS:
This strategy has a one flaw. When you use repository expressions you cannot use the ignore property. But I never find another way to do so.

Is there a way of comparing all the values within 2 entities?

I'm using EF4.3 so I'm referring to entities, however it could apply to any class containing properties.
I'm trying to figure out if its possible to compare 2 entities. Each entity has properties that are assigned values for clarity let say the entity is 'Customer'.
public partial class Customer
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
...
...
}
The customer visits my website and types in some details 'TypedCustomer'. I check this against the database and if some of the data matches, I return a record from the database 'StoredCustomer'.
So at this point I've identified that its the same customer returning but I wan't to valid the rest of the data. I could check each property one by one, but there are a fair few to check. Is it possible to make this comparison at a higher level which takes into account the current values of each?
if(TypedCustomer == StoredCustomer)
{
.... do something
}
If you're storing these things in the database, it is logical to assume you'd also have a primary key called something like Id.
public partial class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
...
...
}
Then all you do is:
if(TypedCustomer.Id == StoredCustomer.Id)
{
}
UPDATE:
In my project, I have a comparer for these circumstances:
public sealed class POCOComparer<TPOCO> : IEqualityComparer<TPOCO> where TPOCO : class
{
public bool Equals(TPOCO poco1, TPOCO poco2)
{
if (poco1 != null && poco2 != null)
{
bool areSame = true;
foreach(var property in typeof(TPOCO).GetPublicProperties())
{
object v1 = property.GetValue(poco1, null);
object v2 = property.GetValue(poco2, null);
if (!object.Equals(v1, v2))
{
areSame = false;
break;
}
});
return areSame;
}
return poco1 == poco2;
} // eo Equals
public int GetHashCode(TPOCO poco)
{
int hash = 0;
foreach(var property in typeof(TPOCO).GetPublicProperties())
{
object val = property.GetValue(poco, null);
hash += (val == null ? 0 : val.GetHashCode());
});
return hash;
} // eo GetHashCode
} // eo class POCOComparer
Uses an extension method:
public static partial class TypeExtensionMethods
{
public static PropertyInfo[] GetPublicProperties(this Type self)
{
self.ThrowIfDefault("self");
return self.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where((property) => property.GetIndexParameters().Length == 0 && property.CanRead && property.CanWrite).ToArray();
} // eo GetPublicProperties
} // eo class TypeExtensionMethods
Most simple seems to use reflexion : get the properties and/or fields you want to compare, and loop through them to compare your two objects.
This will be done with getType(Customer).getProperties and getType(Customer).getFields, then using getValue on each field/property and comparing.
You might want to add custom informations to your fields/properties to define the ones that needs
comparing. This could be done by defining a AttributeUsageAttribute, that would inherit from FlagsAttribute for instance. You'll then have to retrieve and handle those attributes in your isEqualTo method.
I don't think there's much of a purpose to checking the entire object in this scenario - they'd have to type every property in perfectly exactly as they did before, and a simple "do they match" doesn't really tell you a lot. But assuming that's what you want, I can see a few ways of doing this:
1) Just bite the bullet and compare each field. You can do this by overriding the bool Equals method, or IEquatable<T>.Equals, or just with a custom method.
2) Reflection, looping through the properties - simple if your properties are simple data fields, but more complex if you've got complex types to worry about.
foreach (var prop in typeof(Customer).GetProperties()) {
// needs better property and value validation
bool propertyMatches = prop.GetValue(cust1, null)
.Equals(prop.GetValue(cust2, null));
}
3) Serialization - serialize both objects to XML or JSON, and compare the strings.
// JSON.NET
string s1 = JsonConvert.SerializeObject(cust1);
string s2 = JsonConvert.SerializeObject(cust2);
bool match = s1 == s2;

Categories