Can I have customize getter and setter for Realm in c#? - c#

I have a RealmObject extended class. Some of its properties are declared like this:
public String Name { get; set; }
public int Age { get; set; }
These are stored in the Realm data base when I save the object. For the other one, I need a custom setter like this:
private double _amount;
public double Amount
{
get { return _amount; }
set
{
_amount = value;
NotifyPropertyChanged();
}
}
And this one isn't stored. Can someone help me?
Thanks by advance

Realm will only store properties that have an automatic getter and setter, because it uses compile-time IL generation to replace the implementation with calls into the database. If you want to customize the getter and setter, you need to define your fields as properties instead:
private double _amount { get; set; }
public double Amount
{
get { return _amount; }
set { ... }
}
Realm will use the _amount property, while your app can use the public Amount one.
On a side note, you don't need to call NotifyPropertyChanged for persisted properties because Realm already handles INotifyPropertyChanged events for you. So public double Amount { get; set; } is enough to raise property changed notifications.

Related

Showing a SelectedItem's Property

So I enabled a rightclick option for my DataGrid. I want to display just one property of the selecteditem but it's not behaving like how I would like. It displays my namespace and extra.
public class Paymentinfo
{
public int PaymentNo { get; set; }
public String Date { get; set; }
public double Payment { get; set; }
public double Principle { get; set; }
public double Interest { get; set; }
public double Balance { get; set; }
}
private void MenuItem_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show(AmortGrid.SelectedItem.ToString());
}
I am trying to implement this without using a viewmodel! If I put a breakpoint where Messagebox is and put the cursor over the selectedItem then it'll display the properties paymentNo-date-payment-principle-interest-balance. The only value I require is PaymentNo
was hoping it'd be something like this
MessageBox.Show(AmortGrid.SelectedItem.PaymentNo.ToString());
When you call ToString() like that, you get the name of the class type, which is what you're seeing.
If that's a collection of Paymentinfo, cast SelectedItem back to that type first:
MessageBox.Show(((Paymentinfo)AmortGrid.SelectedItem).PaymentNo.ToString());
FWIW, I'd reconsider the ViewModel. Far easier to test your code if you get it out of the code-behind.
You'd be able to bind your SelectedItem directly to a property in the ViewModel (perhaps called SelectedPaymentinfo), and then there'd be no messing around with casting.
You can also set the SelectedValuePath and instead of using SelectedItem use SelectedValue.
Create a ToString() method on PaymentInfo.
public class Paymentinfo
{
public override string ToString()
{
return PaymentNo.ToString();
}
}

Using {set; get;} instead of {get; set;}

In C# and its cousin languages, we always use
public string SomeString { get; set;}
But you can also use ( I found this out only recently and while fooling around with the compiler )
public string SomeString { set; get; }
I do not have any formal training in programming and everything is self-tought. I have been using { get; set; } without any thought just like we use 1 + 1 = 2 Is the order of { get; set; } just a convention or is it necessary to maintain this order or is it some remnant of a bygone era of C history like the way we define conventional electric current flowing from positive to the negative terminal when it is actually the other way around?
It is purely a convention. It makes no difference which order they appear in.
There is no difference.
It is exactly as if you had implemented the getter first in your class body, and the setter after it. The functions would still do exactly the same:
public String getSomeString() { return someString; }
public void setSomeString(String value) { someString=value; }
Whether they are written in that order
public void setSomeString(String value) { someString=value; }
public String getSomeString() { return someString; }
or the opposite. Wouldn't they?
I would however suggest to stick to one order in your code. Less entropy is always better :)
There is no difference.
According to the C# Language Specification http://msdn.microsoft.com/en-us/library/ms228593.aspx, 10.7.2 Accessors (page 324)
The accessor-declarations of a property specify the executable
statements associated with reading and writing that property.
accessor-declarations:
get-accessor-declaration set-accessor-declaration
set-accessor-declaration get-accessor-declaration
As shown it states either order has the same effect
Internally Get and Set are methods like this
private PropertyType Get() {}
private Set(value as PropertyType) {}
Since order of declaration of methods is not important, same case goes here.
MSDN:
The body of the get accessor is similar to that of a method. It must return a value of the property type.
The set accessor is similar to a method that returns void. It uses an implicit parameter called value, whose type is the type of the property.
{ get; set; } is just a shortcut so you don't have to write getters and setters for every field you want to expose. It's the same as when you write
public string GetSomeString() { }
public void SetSomeString(string value) { }
Does it matter, which one you write first? Of course not.
Just a convention you can use any of these when defining parameters:
public string SomeString { get; set; }
public string SomeString2 { set; get; }
public string someString2;
public string SomeString21
{
get { return someString2; }
set { someString2 = value; }
}
public string SomeString22
{
set { someString2 = value; }
get { return someString2; }
}
public string SomeString23
{
set { someString2 = value; }
}
public string SomeString24
{
get { return someString2; }
}
As others have already pointed out, there is no difference and it is just a convention. But to prove that up, you can see how compiler actually treats your code, given the following:
public class C
{
public string SomeString { get; set;}
public string SomeString2 { set; get; }
}
This will be treated as:
public class C
{
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string <SomeString>k__BackingField;
[CompilerGenerated]
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string <SomeString2>k__BackingField;
public string SomeString
{
[CompilerGenerated]
get
{
return <SomeString>k__BackingField;
}
[CompilerGenerated]
set
{
<SomeString>k__BackingField = value;
}
}
public string SomeString2
{
[CompilerGenerated]
get
{
return <SomeString2>k__BackingField;
}
[CompilerGenerated]
set
{
<SomeString2>k__BackingField = value;
}
}
}
As you can see, in both of them a new BackingField is generated by compiler and the body of two properties are same exactly.
The reference.

Get property value by name using reflection

Lets say I have the following class:
public class Provider
{
...
public sealed class Slice
{
public readonly double firstName;
public readonly double secondName;
public readonly double thirdName;
...
}
...
}
This class is used to hold a sliding time series and the contained Slice class is the return value. (Provider.Last property returns the latest instance of Slice).
I need to get the value of the properties of that latest returned Slice class by name of the property.
PropertyInfo secondNameProperty = Provider.Last.GetType().GetProperty("secondName");
double secondNameValue = (double)secondNameProperty.GetValue(Provider.Last, null);
GetProperty returns null. How can I do this?
Look at your Slice class:
public sealed class Slice
{
public readonly double firstName;
public readonly double secondName;
public readonly double thirdName;
...
}
Those aren't properties. They're fields. Either make them properties, or use Type.GetField() instead. Using properties would generally be a better idea, IMO, and needn't be hard. For example, if you just wanted to make them publicly read-only, you could use:
public sealed class Slice
{
public double FirstName { get; private set; }
public double SecondName { get; private set; }
public double ThirdName { get; private set; }
...
}
Alternatively you could declare read-only fields directly, and then expose them via properties. It's a bit more work than using automatically implemented properties, but it removes the potential for setting the property within Slice itself.
(As an aside, do you really have a firstName field of type double? Odd.)
As Jon Skeet says, these aren't properties. Readonly properties would look like this
public sealed class Slice
{
public double FirstName { get; private set }
public double SecondName { get; private set }
public double ThirdName { get; private set }
...
}
or
public sealed class Slice
{
private double _firstName;
public double FirstName { get { return _fristName; } }
private double _secondName;
public double SecondName { get { return _secondName; } }
private double _thirdName;
public double ThirdName { get { return _thirdName; } }
...
}
You can use GetMember() - Members include properties, methods, fields, events, and so on.
Or use Jon Skeet's answer.
Note, the if you use GetField() and later change your fields to properties, GetMember() will continue to find the Field or Property in question without refactoring the code, whereas GetField() will return null.
http://msdn.microsoft.com/en-us/library/xdtchs6z.aspx

Auditing rows added to Azure table storage

I have created the following class which I believe gives me some good auditing capabilities for data rows in certain tables that require it. Here is the class I am using:
public class AuditableTableServiceEntity : TableServiceEntity
{
protected AuditableTableServiceEntity()
: base()
{
}
protected AuditableTableServiceEntity(string pk, string rk)
: base(pk, rk)
{
}
#region CreatedBy and ModifiedBy
private string _CreatedBy;
[DisplayName("Created By")]
public string CreatedBy
{
get { return _CreatedBy; }
set { _CreatedBy = value; Created = DateTime.Now; }
}
[DisplayName("Created")]
public DateTime? Created { get; set; }
private string _ModifiedBy;
[DisplayName("Modified By")]
public string ModifiedBy
{
get { return _ModifiedBy; }
set { _ModifiedBy = value; Modified = DateTime.Now; }
}
[DisplayName("Modified")]
public DateTime? Modified { get; set; }
#endregion
}
Can anyone out there suggest any additional changes that I might consider for this class. I believe it is okay but as I need to implement this for many classes I would like to hear if anyone can suggest any changes or additions.
private string _ModifiedBy;
[DisplayName("Modified By")]
public string ModifiedBy
{
get { return _ModifiedBy; }
set { _ModifiedBy = value; Modified = DateTime.Now; }
}
will cause a stack overflow: setting the value of a property in a setter calls the setter, which sets the value of the property, which calls the setter, and so on.
You could set the properties in a constructor, but then things break if an instance is serialized and deserialized: when you deserialize it, the public parameterless constructor is called, and the setter is called... which sets the property to the date and time that the object was deserialized, not the stored value.
A better pattern might be to create another table for auditable events. This might look something like this:
public class Audit
{
public string ModifiedBy { get; set; }
public DateTime DateModified { get; set; }
public Type ObjectType { get; set; }
public string Field { get; set; }
public object OldValue { get; set; }
public object NewValue { get; set; }
public static void Record(string user, Type objectType, object oldValue, object newValue)
{
Audit newEvent = new Audit
{
ModifiedBy = user,
DateModified = DateTime.UtcNow, // UtcNow avoids timezone issues
ObjectType = objectType,
OldValue = oldValue,
NewValue = newValue
};
Save(newEvent); // implement according to your particular storage classes
}
}
Then, whenever you make changes to an object you want to audit, call Audit.Record() like so:
public class SomeKindOfAuditableEntity
{
private string _importantFieldToTrack;
public string ImportantFieldToTrack
{
get { return _importantFieldToTrack; }
set
{
Audit.Record(GetCurrentUser(), this.GetType(), _importantFieldToTrack, value);
_importantFieldToTrack = value;
}
}
}
This way you store a log of all changes that happen to all "interesting" properties of your tables. This has a few other advantages:
you see the old and new values of each change
the audit log is stored in a different place from the data itself, separating concerns
you don't need to have a base class for your data classes
the audit for old changes is kept around so you can go back through the entire log of the object's changes
The principal disadvantage is that you need to add code to each setter for each property you're interested in. There are ways to mitigate this with attributes and reflection and aspect-oriented programming -- see for instance Spring's implementation here: http://www.springframework.net/doc-latest/reference/html/aop.html -- in essence, you'd create an attribute for the properties you'd like to track.
The other disadvantage is that you'll consume lots of storage for the audit log - but you can have a background process that trims down the old entries periodically as you see fit.

How to serialize a protected property in wcf

I have two classes (Person and Address) that i need to send via wcf, the classes look like this:
public class PersoanaFizica :IExtensibleDataObject
{
[DataMember]
private Guid _id;
[DataMember(Name = "Id")]
protected virtual Guid Id
{
get { return _id; }
set { _id = value; }
}
private ExtensionDataObject _extensionData;
public virtual ExtensionDataObject ExtensionData
{
get
{
return _extensionData;
}
set
{
_extensionData = value;
}
}
private string _firstName;
[Searchable(PropertyName="FirstName")]
[DataMember]
public virtual string FirstName
{
get { return this._firstName; }
set { this._firstName = value; }
}
private string _lastName;
[Searchable(PropertyName="LastName")]
[DataMember]
public virtual string LastName
{
get { return this._lastName; }
set { this. _lastName = value; }
}
private Address _address;
[Searchable(PropertyName="Address")]
[DataMember]
public virtual Address Address
{
get { return this._address; }
set { this._address = value; }
}
}
public class Address : IExtensibleDataObject
{
[DataMember]
private Guid _id;
[DataMember]
public virtual Guid Id
{
get { return _id; }
set { _id = value; }
}
private ExtensionDataObject _extensionData;
public virtual ExtensionDataObject ExtensionData
{
get
{
return _extensionData;
}
set
{
_extensionData = value;
}
}
private string _country;
[Searchable(PropertyName="Country")]
[DataMember]
public virtual string Country
{
get { return this._country; }
set { this._country = value; }
}
// and some other properties related to the address
}
The problem is that when i try to send them via wcf, the client receives the Id properties set to 00000-0000-00000-00000 or something like this.
Any idea why this is happening? And how to serialize the proper values?
nope... did not help. I just looked at
the code generated by svcutil.exe
(thats what i use to generate my
client) and i couldn't find an Id
property at all. I tried changing the
protected keyword to public and
everything worked fine. It seems that
the problem is with the fact that i
need the properties to be protected
and not public.
Denis - any chance at all that your WCF client uses the XmlSerializer (which only serializes public read/write properties with a get and set method) instead of the DataContractSerializer?? The DataContractSerializer would definitely serialize a protected property or field - it really doesn't care about the .NET visibility modifiers....
You should see this in the WCF client side proxy being generated - do you have [DataContract] and [DataMember] attributes there, or do you see [XmlElement] and so forth?? Does your class in the WCF client side proxy have a [DataContractAttribute] or a [XmlTypeAttribute] on it??
You should not be marking both the field and the property with DataMember attributes! I have a feeling this is probably what's causing the issue you're seeing but I don't know that for sure. But basically by marking both the field and its backing property as DataMember's you are serializing the value twice and it will be deserialized twice and depending upon how your client-side code is generated this may even result in storing the value twice.
So long story short, mark either your fields as DataMember or the properties, but not both. Marking the fields may require you to specify a Name on the DataMemberAttribute in order for the client-side code generation to create the expected property names.
You don't initialize the properties in some way, so they have their default value assigned. If you assign a value to them, that should be properly send.

Categories