Class instance not initialized, bug?

T

TEK

Hello

We're having a issue with a part of our app that is very strange, and
I'm unable to see that it should be possible.

We have:
A collection (ActivityCollection) that is inherited from a general,
abstract collection class that implements ITypedList and IBindingList

When the program execute, the ITypedList.GetItemProperties method is
beeing called, but it is beeing called on a uninitialized instance of
the class. I cannot see how that should be possible!

As you can see below, for the sake of testing, we added a private
string called _initializeStatus. In the class definition it is set to
"constructor not called" and in the constructor it is set to
"constructor called". Except form that, it's never changed or accessed.

During debugging, we can see that this property is actually
uninitialized, and by that I mean equal to null.
How is this possible? Is there a bug in the .Net framework? Is it
possible to, for example by reflection, bypass the actuall class
initialization?
Is there any known bugs that is able to explain this behaviour?

I may comment that the TypedCollection class is the base class of
hundereds of other classes, all buildt on the same pattern. It's a
large application, and this issue is only seen on two of the
collections. It only occures when the control (a grid) using it is
beeing initialized and it seems like it is never actually used for
anything. However, it does cause problems in the
ITypedList.GetItemProperties as the state of the class is totally
unexpected.
(and it bothers me that something like this at all is possible)


Code extraction of the two classes used is shown below?


[Serializable]
[TypedCollection(typeof(ActivityEntity))]
public class ActivityCollection : TypedObjectCollection{
public ActivityCollection() : base(){}
[snip]


[Serializable]
public abstract class TypedObjectCollection : ObjectCollection,
ITypedList, IBindingList{
[NonSerialized]
bool _sortNeeded = true;
private string _initalizeStatus = "constructor not called";
private Type _containedType = null;
private static PropertyComparer _propertyComparer = new
PropertyComparer();
private static Hashtable _propertyDescriptorsCache = new
Hashtable();

protected TypedObjectCollection(){
_initalizeStatus = "constructor called";
[snip]

[Serializable]
public class ObjectCollection : CollectionBase, ICloneable{
public ObjectCollection(){
}

[snip]
 
S

Stoitcho Goutsev \(100\)

TEK,

There is difference between type intialization and instance initiazlization.
C# construction for type initializer is static constructor where instances
are initialized by instance constructors. There might be only one static
constructors, but many instance constructors. .NET runtimes guarantees that
the static constructor will be called before a static member of the type is
used. Because there is only one type initializer there cannot be any
confusion. On the other hand instance constructors can be more than one.
Only the constructor used to create the instance is called by the .NET
runtime. If one needs to call some of the other constructors as part of the
initialization one can call it explicitly using *this*keyword.

About your code sample:
1. Your _initalizeStatus is instance field and your constructor is instance
construcor as such we cannot say that the type is not initialized and it
most definitely is.
2. Your code doesn't show it, but if you have more than one constructors it
is possible that you use the other constructor to create and initialize the
instance and if you don't call the parameterless constructor it is possible
that your status field never get set to "constructor called". However it
must be set to "constructor not called" since when this initialization code
is copied to all declared constructors.


From your post I didn't understand very well if you get the "constructor not
called" set.

What is the value of the _initalizeStatus field? Is it *null* or
"constructor called"? *null* shouldn't happen.

How do you create the instance of the ActivityCollection?

Can you post some somple compilable sample that we can play with?



--
HTH
Stoitcho Goutsev (100)




TEK said:
Hello

We're having a issue with a part of our app that is very strange, and
I'm unable to see that it should be possible.

We have:
A collection (ActivityCollection) that is inherited from a general,
abstract collection class that implements ITypedList and IBindingList

When the program execute, the ITypedList.GetItemProperties method is
beeing called, but it is beeing called on a uninitialized instance of
the class. I cannot see how that should be possible!

As you can see below, for the sake of testing, we added a private
string called _initializeStatus. In the class definition it is set to
"constructor not called" and in the constructor it is set to
"constructor called". Except form that, it's never changed or accessed.

During debugging, we can see that this property is actually
uninitialized, and by that I mean equal to null.
How is this possible? Is there a bug in the .Net framework? Is it
possible to, for example by reflection, bypass the actuall class
initialization?
Is there any known bugs that is able to explain this behaviour?

I may comment that the TypedCollection class is the base class of
hundereds of other classes, all buildt on the same pattern. It's a
large application, and this issue is only seen on two of the
collections. It only occures when the control (a grid) using it is
beeing initialized and it seems like it is never actually used for
anything. However, it does cause problems in the
ITypedList.GetItemProperties as the state of the class is totally
unexpected.
(and it bothers me that something like this at all is possible)


Code extraction of the two classes used is shown below?


[Serializable]
[TypedCollection(typeof(ActivityEntity))]
public class ActivityCollection : TypedObjectCollection{
public ActivityCollection() : base(){}
[snip]


[Serializable]
public abstract class TypedObjectCollection : ObjectCollection,
ITypedList, IBindingList{
[NonSerialized]
bool _sortNeeded = true;
private string _initalizeStatus = "constructor not called";
private Type _containedType = null;
private static PropertyComparer _propertyComparer = new
PropertyComparer();
private static Hashtable _propertyDescriptorsCache = new
Hashtable();

protected TypedObjectCollection(){
_initalizeStatus = "constructor called";
[snip]

[Serializable]
public class ObjectCollection : CollectionBase, ICloneable{
public ObjectCollection(){
}

[snip]
 
T

TEK

Thanks for your reply.
From your post I didn't understand very well if you get the "constructor not
called" set.

What is the value of the _initalizeStatus field? Is it *null* or
"constructor called"? *null* shouldn't happen.

It is *null*, and I agree, it should not happend.
How do you create the instance of the ActivityCollection?

I'm unable to locate where the actual instance is created. I have tried
to debug the issue, and I can see only one instance of
ActivityCollection beeing created before this happend, and that
instance is created using "new ActivityCollection()".
But that is not the instance causing the error (different HashCodes)
I'm wondering if it might be placed by a 3rd party component using
reflection or something, but I'm not sure.
Can you post some somple compilable sample that we can play with?
No, I cannot see any way for me to reproduce this (except posting the
source code for our whole system, and that's a "no can do"...)

HEY!!!
While writing this I was able to find what creates the collection!
The collection is created in the initialize method of the form by this
line of code:
this._activityList.Activities =
((ByggOffice.Bali.BusinessEntities.ActivityCollection)(resources.GetObject("_activityList.Activities")));

Meaning that unwrapping/unserializing this must fail halfway or
something.
The collection should not have been serialized, but that is an easy fix
(adding a design time attribute to the control)

It's still very strange that this actually is possible, should'nt the
deserialization have failed, preferrable with some kind of resonable
error message?
Right now I'm just glad to have (at least I think so) found the reson
for this. I'll do some more checking to ensure that it will work after
I have removed this, but I'm quite sure it will.

Noisy little bugger that one....

Regards, TEK
TEK,

There is difference between type intialization and instance initiazlization.
C# construction for type initializer is static constructor where instances
are initialized by instance constructors. There might be only one static
constructors, but many instance constructors. .NET runtimes guarantees that
the static constructor will be called before a static member of the type is
used. Because there is only one type initializer there cannot be any
confusion. On the other hand instance constructors can be more than one.
Only the constructor used to create the instance is called by the .NET
runtime. If one needs to call some of the other constructors as part of the
initialization one can call it explicitly using *this*keyword.

About your code sample:
1. Your _initalizeStatus is instance field and your constructor is instance
construcor as such we cannot say that the type is not initialized and it
most definitely is.
2. Your code doesn't show it, but if you have more than one constructors it
is possible that you use the other constructor to create and initialize the
instance and if you don't call the parameterless constructor it is possible
that your status field never get set to "constructor called". However it
must be set to "constructor not called" since when this initialization code
is copied to all declared constructors.


From your post I didn't understand very well if you get the "constructor not
called" set.

What is the value of the _initalizeStatus field? Is it *null* or
"constructor called"? *null* shouldn't happen.

How do you create the instance of the ActivityCollection?

Can you post some somple compilable sample that we can play with?



--
HTH
Stoitcho Goutsev (100)




TEK said:
Hello

We're having a issue with a part of our app that is very strange, and
I'm unable to see that it should be possible.

We have:
A collection (ActivityCollection) that is inherited from a general,
abstract collection class that implements ITypedList and IBindingList

When the program execute, the ITypedList.GetItemProperties method is
beeing called, but it is beeing called on a uninitialized instance of
the class. I cannot see how that should be possible!

As you can see below, for the sake of testing, we added a private
string called _initializeStatus. In the class definition it is set to
"constructor not called" and in the constructor it is set to
"constructor called". Except form that, it's never changed or accessed.

During debugging, we can see that this property is actually
uninitialized, and by that I mean equal to null.
How is this possible? Is there a bug in the .Net framework? Is it
possible to, for example by reflection, bypass the actuall class
initialization?
Is there any known bugs that is able to explain this behaviour?

I may comment that the TypedCollection class is the base class of
hundereds of other classes, all buildt on the same pattern. It's a
large application, and this issue is only seen on two of the
collections. It only occures when the control (a grid) using it is
beeing initialized and it seems like it is never actually used for
anything. However, it does cause problems in the
ITypedList.GetItemProperties as the state of the class is totally
unexpected.
(and it bothers me that something like this at all is possible)


Code extraction of the two classes used is shown below?


[Serializable]
[TypedCollection(typeof(ActivityEntity))]
public class ActivityCollection : TypedObjectCollection{
public ActivityCollection() : base(){}
[snip]


[Serializable]
public abstract class TypedObjectCollection : ObjectCollection,
ITypedList, IBindingList{
[NonSerialized]
bool _sortNeeded = true;
private string _initalizeStatus = "constructor not called";
private Type _containedType = null;
private static PropertyComparer _propertyComparer = new
PropertyComparer();
private static Hashtable _propertyDescriptorsCache = new
Hashtable();

protected TypedObjectCollection(){
_initalizeStatus = "constructor called";
[snip]

[Serializable]
public class ObjectCollection : CollectionBase, ICloneable{
public ObjectCollection(){
}

[snip]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top