Design time serialization in C# - c#

I have created a non-visual component in C# which is designed as a placeholder for meta-data on a form.
The component has a property which is a collection of custom objects, this object is marked as Serializable and implements the GetObjectData for serilizing and public constuctor for deserilizing.
In the resx file for the form it will generate binary data for storing the collection, however any time I make a change to the serialized class I get designer errors and need to delete the data manually out of the resx file and then recreate this data.
I have tried changing the constuctor to have a try / catch block around each property in the class
try
{
_Name = info.GetString("Name");
}
catch (SerializationException)
{
this._Name = string.Empty;
}
but it still crashes. The last error I got was that I had to implement IConvertible.
I would prefer to use xml serialization because I can at least see it, is this possible
for use by the designer?
Is there a way to make the serialization more stable and less resistant to changes?
Edit:
More information...better description maybe
I have a class which inherits from Component, it has one property which is a collection of Rules. The RulesCollection seems to have to be marked as Serializable, otherwise it does not retain its members.
The Rules class is also a Component with the attribute DesignTimeVisible(false) to stop it showing in the component tray, this clas is not marked Serializable.
Having the collection marked as Serializable generates binary data in the resx file (not ideal) and the IDE reports that the Rules class is not Serializable.
I think this issue is getting beyond a simple question. So I will probably close it shortly.
If anyone has any links to something similar that would help a lot.

You might want to try the alternate approach of getting everything to serialize as generated code. To do that is very easy. Just implement your non-visual class from Component. Then expose your collection as you already are but ensure each object placed into the collection is itself derived from Component. By doing that everything is code generated.

I have since discovered where I was going wrong.
The component I was implementing a custom collection (inherited from CollectionBase), I changed this to a List and added the DesignerSerializationVisibility(DesignerSerializationVisibility.Content) attribute to the List property, this list is also read-only. This would then produce code to generate all the components properties and all the entries in the List.
The class stored in the list did not need any particuar attributes or need to be serializble.
private List<Rule> _Rules;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<Rule> Rules
{
get { return _Rules; }
}

Could you put more code up of the class that is having the serialization issue, maybe the constructor and the property to give reference to the variables you're using.
Just a note:
I've had a lot of issues with the visual designer and code generation, if I've got a property on a control then generally I put
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
on the property and handle the initialization myself.

Related

Deserialization of changed class

I am working on a program, where I save it's project files by serializing Project class.
Because I am still working on it, some classes, that are part of Project class, do change from time to time (e.g. class got new property). It makes "simple" deserialization impossible.
Is there any way to solve it ? I mean, without writng custom serializer ? (which probably is something high above my level for now)
Just in case, I am using BinaryFormatter.
I hope I understood your problem correctly. You have a class serialized to a file which you have since changed in the program (e.g you have added another property). Now you want to deserialize this class from the file. This is not a problem as long as you have only added new properties. They will be ignored by the deserializer. It creates a new instance of your class (that is the reason why serializable classes have to have a default constructor) and tries to fill the properties it finds in the stream to derserialize. If you change a property's type or remove a property, you won't be able to deserialize the original file.
One workaround for removing properties is to keep them in the class, but just stop using them in the rest of the program. A workaround for properties that have been changed to a different type could look something like this:
[Serializable]
public class MyClass
{
int? newProperty;
[XmlElement("Property")]
public string OldProperty
{
get { return string.Empty; }
set
{
if (!newProperty.HasValue)
{
int temp;
if (int.TryParse(value, out temp))
{
newProperty.Value = temp;
}
}
}
}
public int NewProperty
{
get { return newPropery.HasValue ? newProperty.Value : 0; }
set { newProperty.Value = value; }
}
}
From my experience, I've found using BinaryFormatter for serialization/de-serialization of data types that are going to change a really bad idea. If something changes in your data type, from what I know the BinaryFormatter will fail in the process.
To overcome this issue in the data types I was using, I had to write my own serializer, which wasn't actually that much of a major task. You can use the BinaryReader and BinaryWriter classes to read and write the data in and out of your type. That way you can control the data you are expecting and handle any missing data either by adding default values, skipping the property altogether, or throwing some form of Exception to signify corrupt data. Refer to the MSDN article links above for more information.
With help from Merlyn Morgan-Graham's comments I've found solution, that will work for me.
Versioning described in Version Tolerant Serialization is really good idea, but when I use only [Serializable] attribute.
I forgot to write (my mistake), that I am using ISerializable interface.
I've found, that in deserialization constructor SerializationInfo object has MemberCount property, which solves my problem if I only add new properties/members from time to time. With this information, new members/properties, that can't be deserialized from older file, can be set to default or maybe I can use some prompt form.
Other way here would be using something like assembly version in deserialization, as a first deserialized member. This can solve deserialization problems with more complex class changes.
Either way, I agree with Merylin - "if you can't script something, you shouldn't be building it". ;)

Binding a (complex) class property to CF.NET in C#

I am trying to make a 2-way binding of a class property.
public class MyClass{
public MyField AField1{get;set;};
public MyField AField2{get;set;};
}
public class MyField{
public string Value {get; set}
}
MyClass _class = MyClass();
_dv.DataSource = _class;
Databinding text object displays MyField class name instead of Value Property. I also tried to enter:
DataMember = "AField1.Value";
Is there any way to bind (2-way) AField1.Value of a class MyClass to a visual control?
It's a pain. There's no built-in way to achieve this in .NET, so I can safely say, even less in the CF.
You can get started with this article on MSDN Blogs, but it's pretty limited as you can only get one level of nested property bindings.
Personnally, I ended up writing a custom BindingSource, based on code that lies somewhere on the internets. I can't give you source code of my rewrite as it's property of my employer, but here's the link to the project that got me started.
There are a few drawbacks to the code provided : some of his namespaces are System.ComponentModel, and VS2010 didn't seem to like, so I had to rename them. And a few more issues in design time that can make it a pain to use (so you'll want to fix that too), like loosing the list of properties when you make a spelling mistake and so on...
But it's the best shot (IMHO) at creating a good BindingSource that handles nested objects, and you'll get the idea of what needs to be done to achieve your nested bindings.
The last drawback (and biggest probably, but I have no experience with CF) is that the project is written for the regular .NET Framework, so it's likely that you will have to rewrite it entirely.
Hope that helps....
Edit. Uh oh, I've been grave-digging without noticing... sorry.
PS. Another idea is to simply create one binding source for each of your nested objects, but it gets messy (IMO) if your object hierarchy is complex.

Properties vs. Fields: Need help grasping the uses of Properties over Fields

First off, I have read through a list of postings on this topic and I don't feel I have grasped properties because of what I had come to understand about encapsulation and field modifiers (private, public..ect).
One of the main aspects of C# that I have come to learn is the importance of data protection within your code by the use of encapsulation. I 'thought' I understood that to be because of the ability of the use of the modifiers (private, public, internal, protected). However, after learning about properties I am sort of torn in understanding not only properties uses, but the overall importance/ability of data protection (what I understood as encapsulation) within C#.
To be more specific, everything I have read when I got to properties in C# is that you should try to use them in place of fields when you can because of:
1) they allow you to change the data type when you can't when directly accessing the field directly.
2) they add a level of protection to data access
However, from what I 'thought' I had come to know about the use of field modifiers did #2, it seemed to me that properties just generated additional code unless you had some reason to change the type (#1) - because you are (more or less) creating hidden methods to access fields as opposed to directly.
Then there is the whole modifiers being able to be added to Properties which further complicates my understanding for the need of properties to access data.
I have read a number of chapters from different writers on "properties" and none have really explained a good understanding of properties vs. fields vs. encapsulation (and good programming methods).
Can someone explain:
1) why I would want to use properties instead of fields (especially when it appears I am just adding additional code
2) any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
3) Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Thanks and sorry for the long post - I didn't want to just ask a question that has been asked 100x without explaining why I am asking it again.
1) why I would want to use properties
instead of fields (especially when it
appears I am just adding additional
code
You should always use properties where possible. They abstract direct access to the field (which is created for you if you don't create one). Even if the property does nothing other than setting a value, it can protect you later on. Changing a field to a property later is a breaking change, so if you have a public field and want to change it to a public property, you have to recompile all code which originally accessed that field.
2) any tips on recognizing the use of
properties and not seeing them as
simply methods (with the exception of
the get;set being apparent) when
tracing other peoples code?
I'm not totally certain what you are asking, but when tracing over someone else's code, you should always assume that the property is doing something other than just getting and setting a value. Although it's accepted practice to not put large amounts of code in getters and setter, you can't just assume that since it's a property it will behave quickly.
3) Any general rules of thumb when it
comes to good programming methods in
relation to when to use what?
I always use properties to get and set methods where possible. That way I can add code later if I need to check that the value is within certain bounds, not null etc. Without using properties, I have to go back and put those checks in every place I directly accessed the field.
One of the nice things about Properties is that the getter and the setter can have different levels of access. Consider this:
public class MyClass {
public string MyString { get; private set; }
//...other code
}
This property can only be changed from within, say in a constructor. Have a read up on Dependency Injection. Constructor injection and Property injection both deal with setting properties from some form of external configuration. There are many frameworks out there. If you delve into some of these you will get a good feel for properties and their use. Dependency injection will also help you with your 3rd question about good practice.
When looking at other people's code, you can tell whether something is a method or a property because their icons are different. Also, in Intellisence, the first part of a property's summary is the word Property.
You should not worry about the extra code needed for accessing fields via properties, it will be "optimized" away by the JIT compiler (by inlining the code). Except when it is too large to be inlined, but then you needed the extra code anyway.
And the extra code for defining simple properties is also minimal:
public int MyProp { get; set; } // use auto generated field.
When you need to customize you can alway define your own field later.
So you are left with the extra layer of encapsulation / data protection, and that is a good thing.
My rule: expose fields always through properties
While I absolutely dislike directly exposing fields to the public, there's another thing: Fields can't be exposed through Interfaces; Properties can.
There are several reasons why you might want to use Properties over Fields, here are just a couple:
a. By having the following
public string MyProperty { get; private set; }
you are making the property "read only". No one using your code can modify it's value. There are cases where this isn't strictly true (if your property is a list), but these are known and have solutions.
b. If you decide you need to increase the safety of your code use properties:
public string MyProperty
{
get { return _myField; }
set
{
if (!string.IsNullOrEmpty(value))
{
_myField = value;
}
}
}
You can tell they're properties because they don't have (). The compiler will tell you if you try to add brackets.
It's considered good practise to always use properties.
There are many scenarios where using a simple field would not cause damage, but
a Property can be changed more easily later, i.e. if you want to add an event whenever the value changes or want to perform some value/range checking.
Also, If you have several projects that depend on each other you have to recompile all that depend on the one where a field was changed to a property.
Using fields is usually practiced in private classes that is not intended to share data with other classes, When we want our data to be accessible by other classes we use properties which has the ability to share data with other classes through get and set which are access methods called Auto Properties that have access to data in private classes, also you can use both with access modifiers Full Property in the same class allowing the class to use data privately as data field and in the same time link the private field to a property that makes the data accessible to other classes as well, see this simple example:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
The private string _name is used by the class only, while the Name property is accessible by other classes in the same namespace.
why I would want to use properties instead of fields (especially when it appears I am just adding additional code
You want to use properties over fields becuase, when you use properties you can use events with them, so in a case when you want to do some action when a property changes, you can bind some handlers to PropertyChanging or PropertyChanged events. In case of fields this is not possible. Fields can either be public or private or protected, in case of props you can make them read-only publicly but writable privately.
any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?
A method should be used when the return value is expected to be dynamic every-time you call, a property should be used when the return value is not that greatly dynamic.
Any general rules of thumb when it comes to good programming methods in relation to when to use what?
Yes, I strongly recommend to read Framework Design guidelines for best practices of good programming.
Properties are the preferred way to cover fields to enforce encapsulation. However, they are functional in that you can expose a property that is of a different type and marshal the casting; you can change access modifiers; they are used in WinForms data binding; they allow you to embed lightweight per-property logic such as change notifications; etc.
When looking at other peoples code, properties have different intellisense icons to methods.
If you think properties are just extra code, I would argue sticking with them anyway but make your life easier by auto-generating the property from the field (right-click -> Refactor -> Encapsulate Field...)
Properties allow you to do things other than set or get a value when you use them. Most notably, they allow you to do validation logic.
A Best Practice is to make anything exposed to the public a Property. That way, if you change the set/get logic at a later time, you only have to recompile your class, not every class linked against it.
One caveat is that things like "Threading.Interlocked.Increment" can work with fields, but cannot work with properties. If two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerField, the value will get increased by two even if there is no other locking. By contrast, if two threads simultaneously call Threading.Interlocked.Increment on SomeObject.LongIntegerProperty, the value of that property might get incremented by two, or by one, or by -4,294,967,295, or who knows what other values (the property could be written to use locking prevent values other than one or two in that scenario, but it could not be written to ensure the correct increment by two).
I was going to say Properties (setters) are a great place to raise events like NotifyPropertyChanged, but someone else beat me to it.
Another good reason to consider Properties: let's say you use a factory to construct some object that has a default constructor, and you prepare the object via its Properties.
new foo(){Prop1 = "bar", Prop2 = 33, ...};
But if outside users new up your object, maybe there are some properties that you want them to see as read-only and not be able to set (only the factory should be able to set them)? You can make the setters internal - this only works, of course, if the object's class is in the same assembly as the factory.
There are other ways to achieve this goal but using Properties and varying accessor visibility is a good one to consider if you're doing interface-based development, or if you expose libraries to others, etc.

How to serialize attached properties

I am writing .NET3.5, WPF application using Composite Application Library. Application is divided into several modules.
In infrastructure module I have defined NetworkNode object. The Network module manages a collection of NetworkNodes and uses XmlSerializer to store/load this collection. So far everythings works.
But I have other modules e.g NodeModule. If a NetworkNode was selected in Network module, an event is published to other modules using EventAggregator. These modules can attach various information to the NetworkNode using attached properties.
The problem is the NetworkModule does not know about the other modules, therefor these properties are not serialized. It is possible to somehow list and serialize all properties attached to an object? Or do I have to change the concept and use something else than attached properties?
Regards
You can list all dependency properties (attached or not) defined on an object using DependencyObject.GetLocalValueEnumerator :
LocalValueEnumerator propEnumerator = foo.GetLocalValueEnumerator();
while (propEnumerator.MoveNext())
{
Console.WriteLine ("{0} = {1}",
propEnumerator.Current.Property.Name,
propEnumerator.Current.Value);
}
However, this won't help for XML serialization (unless you implement IXmlSerializable, which is a pain...). You should probably use XamlWriter instead (which I assume is what Drew was talking about, since there is no XamlSerializer...)
Since attached properties aren't visible from a pure CLR perspective, the XmlSerializer has no way to know about them. You would need to switch to use the XamlSerializer architecture in order to be able to serialize both "plain" CLR objects as well as have the special knowledge of DependencyObjects.
If you are using .Net 4.0 (I believe they aren't in .Net 3.5)
You can use either IAttachedPropertyStore or AttachablePropertyServices
Reference Example #1: http://blogs.msdn.com/b/bursteg/archive/2009/05/18/xaml-in-net-4-0-attached-properties-iattachedpropertystore-and-attachablepropertyservices.aspx
Also, generally, the attached property must be defined correctly:
It must be a property of public (or internal works in some scenarios) non-nested type (i.e. it is not declared inside another type), T.
Define a new AttachableMemberIdentifier(T, "MyProperty")
Provide public static methods on T called "SetMyProperty" and "GetMyProperty", i.e. the "MyProperty" part must match your AttachableMemberIdentifier. (You can't use "Foo" as the name in the AttachableMemberIdentifier and call them "SetBar" and "GetBar" because the Xaml serializer stack needs to find them by reflection.) These methods should then leverage AttachablePropertyServices to store the attached property value.
Reference Example #2: http://blogs.msdn.com/b/mwinkle/archive/2009/12/07/attachedproperty-part-2-putting-it-together.aspx

Saving an ArrayList of custom objects to user settings

Is it possible to save an ArrayList of custom objects to the application user settings without resorting to custom serialization?
For example, given a basic data class containing only public get/set properties and private backing fields:
[Serializable]
class SimpleClass()
{
...
}
When I run the following in code, and then restart the application, the ArrayList setting named MyList is always null, ie it was not saved.
if (Properties.Settings.Default.MyList==null)
{
Properties.Settings.Default.MyList=new ArrayList();
}
Properties.Settings.Default.MyList.Add(new SimpleClass(DateTime.Now.ToString()));
Properties.Settings.Default.Save();
I realise that an ArrayList is not typed, ie. it holds a collection of objects. However it is simple to use GetType() on each object to determine the actual type. This should allow serialization to occur, shouldn't it?
I also know how to get around this performing some custom serialization. It's just a pain this doesn't appear to work as it would be by far the most convenient for simpler situations.
Any ideas?
If you are using XML Serialization, you can use the XmlArrayItem attribute.
[XmlArray("Items")]
[XmlArrayItem("A.Thing",typeof(Thing))]
[XmlArrayItem("A.Different.Thing",typeof(Whatzit))]
public System.Collections.ArrayList List;
This requires that you know the different types that may be present in the ArrayList at compile time.

Categories