Why does DependencyObject.MemberwiseClone act this way? - c#

Why does calling ShallowCopy below fail the Debug.Assert? I expect that the two properties are referencing different collections.
public class MyClass : DependencyObject
{
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
"Items",
typeof(ObservableCollection<int>),
typeof(MyClass),
new PropertyMetadata(default(ObservableCollection<int>)));
public ObservableCollection<int> Items
{
get { return (ObservableCollection<int>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public MyClass ShallowCopy()
{
Items = new ObservableCollection<int>();
var copy = (MyClass)this.MemberwiseClone();
copy.Items = new ObservableCollection<int>();
Debug.Assert(!ReferenceEquals(copy.Items,Items), "WHY???");
return copy;
}
}

You cannot clone arbitrary objects. A given object must support being cloned. Calling Object.MemberwiseClone on anything is unsafe by default unless you can show it's safe.
For example, what would cloning a FileStream or a Button do in your mind? It does not make sense.
It's like when you use private reflection to mess with some object's internal state. You get undefined behavior. Really, anything can happen.
If you are curious why you are getting this exact behavior you need to decompile DependencyObject.Items.set to see why are corrupted DependencyObject might misbehave in such a way. My guess: Both the old and the new object are sharing some state due to all fields just being copied over. That's why setting Items on one object also sets it on the other. It's really the same variable underneath.
Object.MemberwiseClone is a design mistake in the .NET Framework because it is not possible to protect that method adequately. It's mere existence is unsafe by default as you found out.

Related

Why use a readonly modifier on a field that changes?

In this tutorial by Josh Smith, a field is defined as readonly:
public class CustomerRepository
{
readonly List<Customer> _customers;
...
public CustomerRepository(string customerDataFile)
{
_customers = LoadCustomers(customerDataFile);
}
...
}
and later the readonly list, _customers, is updated:
public void AddCustomer(Customer customer)
{
if (customer == null)
throw new ArgumentNullException("customer");
if (!_customers.Contains(customer))
{
_customers.Add(customer);
if (this.CustomerAdded != null)
this.CustomerAdded(this, new CustomerAddedEventArgs(customer));
}
}
How this is allowed and what is the point of using readonly?
The List<Customer> variable itself (_customers) is readonly - that means you can't switch it out for an entirely different list, ensuring that everyone that's looking at it will always be seeing the same list. You can, however, still change the elements within that list.
From MSDN (https://msdn.microsoft.com/en-us/library/acdd6hb7.aspx):
The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class
You cannot assign new value to _customers field, but you still change the elements within that list.
_customers.Add(customer); does not update the list. This operator update the content of the list. If you want to update the list you must use something like _customers= .... And this is prevented by the readonly
The point of making the field readonly is that the reference cannot be changed. That means that you cannot write something like
_customers = null;
or
_customers = new List<Customer>();
Invoking the method .Add() accesses the collection through a method, and does not change the reference of the object.
This could be useful to prevent any NullReferenceException.

C# Can/should a List<> of a class be a static member of the same class?

My example:
class MyClass
{
public int a = 1;
public static List<MyClass> list = new List<MyClass>();
}
class Program
{
static void Main(string[] args)
{
MyClass.list.Add(new MyClass() { a = 5 });
MyClass.list.Add(new MyClass() { a = 10 });
foreach (MyClass item in MyClass.list) Console.WriteLine(item.a);
Console.ReadKey();
}
This code works, and shows that my list, which is statically defined within the MyClass class itself, is populating as I'd expect.
Is there any reason not to define my list in this manner?
Such a solution is used sometime, f.e. to implement the Singleton or Register-Resolve patterns.
But you should keep in mind that it's not well suited for multithread environment. Typically, a static collection should be private, and access methods (including property getter and setter) should be synchronized.
In additional, static fields/properties are difficult to an unit testing.
Actually this code shows a lot of sign of (very) bad desing.
First of all one better doesn't make fields public. All other classes/object can now alter the value of that variable in objects. Perhaps you don't see much problems with that, but imagine that at one point in time you want to restrict the range of values that variable can have, or that it depends on the value of another field. Properties (with getters and setters) and methods are used to shield an field from external usage, they need to guarantee that the object always remains in a valid state.
Next about the list, again don't make such lists public - unless you are confident that there is no problem -. But furthermore using statics is by some researchers considered to be bad design as well. The list maintains a state, but since it is static, this is a global state. Global states are problematic since they don't allow (easy) unit testing, and can become problematic if for some reason the list should be not that global.
In case you really want to make some access point for data, you can perhaps consider making a class that stores such list and pass it around in your program.
There are a few exceptions, for instance the Flyweight pattern where one indeed maintains a global state. Those examples are merely used to increase performance. For instance:
public class FlyWeightInstance {
private int value; //<- private field
private static Dictionary<int,FlyWeightInstance> dic = new Dictionary<int,FlyWeightInstance>(); //<- private static cache
private int FlyWeightInstance (int value) { // <-- private constructor
this.value = value;
}
public static FlyWeightInstance (int value) {
FlyWeightInstance res;
if(!dic.TryGetValue(value,out res)) {
res = new FlyWeightInstance(value);
dic.Add(value,res);
}
return res;
}
}

How to fire Dependency property PropertyChangedCallback when instantiating custom type

I have a dependency property setup within a custom control as follows:
public IChartData Data
{
get
{
return (IChartData)GetValue(DataProperty);
}
set
{
SetValue(DataProperty, value);
}
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register
(
"Data",
typeof(IChartData),
typeof(ChartViewUserControl),
new FrameworkPropertyMetadata() { PropertyChangedCallback = UpdateCharting }
);
and its PropertyChangedCallback as such:
private static void UpdateCharting(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Stuff Happens Here
}
As you can see, the dependency property type is IChartData. The reason is that I could be passing one of two types (SimpleChartData or ComplexChartData.) These two types both extend a collection as such:
public class SimpleChartData : ObservableCollection<ChartDataItem>, IChartData
and
public class ComplexChartData : ObservableCollection<SimpleChartData>, IChartData
My issue is that if I create an instance of one of these types and add to the collection, then the PropertyChangedCallback function fires as expected. However, if I need to clear the collection, then I just instantiate it as new but the callback function does not fire. I could create a hack everywhere that the control is used but that's obviously not ideal. How can I get the callback to function to fire when the custom type is instantiated. Other suggestions to solve my problem is of course welcome.
This approach is pretty dirty but will work. Changing value to null and back to old will force you propertychanged callback.
collection.Clear();
foreach(var item in list)
{
// refresh data
var temp = item.Data;
item.Data = null;
item.Data = temp;
collection.Add(item);
}
Sigh... I am a complete idiot. Michael Gunter had commented and pointed out my mistake of posting the wrong callback method. My issue was a combination of carelessness and poor naming. Not only had I posted the wrong method in my code, I had also been checking the wrong method for firing when the Data property was changed. It was working correctly all along and my initial problem was elsewhere. I'm sorry to bother everyone with such a stupid mistake on my part. I do appreciate, however, everyone's input and the extra education that NETscape provided. Thanks to all.

Should composite properties of a Model class be always initialized?

I tried to find a similar question on SO but had no luck. Apologies if it's a duplicate.
What are drawbacks to instantiating class-type variables when they are declared?
In a lot of classes representing Business Object Model we have things like this:
public class RateArea {...}
public class FlatRateSchedule
{
public string ScheduleID {get;set;}
public decimal MaxAmount {get;set;}
}
public class PricingData
{
private List<RateArea> rateAreaList = new List<RateArea>();
private FlatRateSchedule flatRateSchedule = new FlatRateSchedule();
public List<RateArea> RateAreaList
{
get { return rateAreaList; }
set { rateAreaList = value; }
}
public List<FlatRateSchedule> FlatRateScheduleList
{
get { return flatRateScheduleList; }
set { flatRateScheduleList = value; }
}
}
At some point this PricingData class is initialized and some properties are hydrated (but not always all properties).
The thinking being that we're creating "blank" instances of classes so that no properties are ever null. This is convenient because we never have to check if any property is null before accessing it's members. Whether properties are hydrated or not, they would never be "null" to the consuming class. If the properties aren't initialized then code needs to check for null every time before accessing a property.
Is a blanket convention that "all properties of a class should be initialized at all times and never be null" really bad?
Besides using some resources to instantiate and store these "default" class instances, the savings in null-exception-checking code seem to be worth it. Are we missing something?
Not an expert here but
If its a List, it does need to be initialized since you can't add elements if it isn't.
If, throughout the life of your class, your properties may not be always needed you can lazy load them.
You could use .Net 4.0's Lazy<T> class.
From Msdn : "Use an instance of Lazy to defer the creation of a large or resource-intensive object or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program."
Other than that I think it would be intensive for all your properties to be null and have every consuming class do null checks. Lazy<T> solves this.
I like to initialize values to avoid having to check for null throughout my application. I'd probably go with lazy loading:
public List<RateArea> RateAreaList
{
get {
rateAreaList = rateAreaList ?? new List<RateArea>();
return rateAreaList;
}
set { rateAreaList = value; }
}
As long as your properties are only lists (as in your example), it may be a good convention, making your code more compact and easier to read. Lists can be empty, and if you don't need to distinguish between an empty list and a null reference, this works fine. But if your properties contain other "Business Objects", this may not work so easily. Often the construction of those "child" Business Objects cannot or shall not be done at the time when the "parent" object is constructed.

Pros/Cons on Lists with subsidiary objects

I'm again in the position to figure a way out to handle lists with subsidiary objects on our business objects.
Actually, our code often looks like this:
public class Object
{
private List<SubsidiaryObject> subsidiaryObjects = null;
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
if (this.subsidiaryObjects == null)
{
this.subsidiaryObjects = DBClass.LoadListFromDatabase();
}
return this.subsidiaryObjects;
}
set
{
this.subsidiaryObjects = value;
}
}
}
The Con on this:
The property is referenced in presentation layer and used for DataBinding. Releasing the reference to the actual list and replacing it with a new one will end in an referenced list in the GUI that does not have anything left with the list on the object.
The Pro on this:
Easy way of reloading the list (just set the reference to null and then get it again).
I developed another class that uses the following pattern:
public class Object2
{
private readonly List<SubsidiaryObject> subsidiaryObjects = new List<SubsidiaryObject>();
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
return this.subsidiaryObjects;
}
}
public void ReloadSubsidiaryObjects()
{
this.SubsidiaryObjects.Clear();
this.SubsidiaryObjects.AddRange(DBClass.LoadListFromDatabase());
}
}
Pro on this:
Reference is continous.
The Con on this:
Reloading the list is more difficult, since it just cannot be replaced, but must be cleared/filled with reloaded items.
What is your preferred way, for what situations?
What do you see as Pro/Con for either of these to patterns?
Since this is only a general question, not for a specific problem, every answer is welcome.
Do you need the caller to be able to modify the list? If not you should consider returning IEnumerable<T> or ReadOnlyCollection instead. And even if you do, you will probably be better off making cover versions for Add/Remove so you can intercept modifications. Handing a reference to internal state is not a good idea IMO.
A third option would be to go with option 2, but to create a new instance of the Object2 type each time you need to repopulate the list. Without additional context for the question, that is the option I would select, but there may be reasons why you would want to hold on to the original instance.

Categories