Problems creating collection properties

A

Andy B

I am trying to create a property of a class that holds a collection. Inside
the main class is a property that is defined as a collection. When I try to
assign values to it I keep getting all sorts of errors. The main one that I
get now is 'Can't convert Contracts.ContractModel.ContractDefinitions
collection to Contracts.ContractModel.Definition type'.

inside the main Contract class I have the Definitions collection property:

private ContractDefinitions Definitions=null;
public ContractDefinitions Definitions {
get { return this.Definitions; }
set {thisDefinitions=value; }
}
ContractDefinitions is the collection of Definition types. Here is what I
end up getting when I try to assign Definitions to the collection:

//Create a contract object. This works fine
Contract Contract = new Contract();

//create some definitions. This works as well...
Definition Host = new Definition);
Host.Word="Host";
Host.Definition1="A person who pays for and signs the contract";

//Assign the Definition to the collection class by creating it. These 2
lines give me a 'can't convert ContractDefinitions collection to Definition
type' error.
Contract.Definitions.Add(Host); //I get object reference set to a null
reference error//try it by creating an instance of the Deffinitions
collection
ContractDefinitions DefinitionsCollection = new ContractDefinitions();
DefinitionsCollection.Add(Host);

I also tried different ways as well but cant quite figure out how to do
this. The entire 20 class contract set was created from xsd file. Is there
any way I can get this to work?
 
M

Morten Wennevik [C# MVP]

Hi Andy,

You got the name and type switched.

private ContractDefinitions Definitions=null;

public ContractDefinitions Definitions
{
get { return this.Definitions; }
set {thisDefinitions=value; }
}

This is a ContractDefinitions object. The reference to the object and the
name of the property is called Definitions.

If you want a collection of Definitions objects try it the other way around

// Common naming uses lowercase version of the property name for the
// private placeholder.
// Adding _ in front of the name ensures it won't mix with property
// names in Intellisense.
private List<Definition> _definitions

public List<Definition> Definitions
{
get{ return _definitions; }
set{ _definitions = value; }
}

Now, if ContractDefinitions is a collection of Definitions just replace
List<Definition> with ContractDefinitions.
 
M

Marc Gravell

You haven't indicated how ContractDefinitions is declared? I've made
an assmuption of:

class ContractDefinitions : Collection<Definition> { }

(since if it had been an array I wouldn't expect to see a type called
ContractDefinitions)

With which (having fixed the other issues [below]) works just fine. In
real code I would expect the definitions field to auto-initialize to
an empty collection and only have a getter (not least; since this
makes deserialization possible), but "as is" you have to use the code
as you posted:

ContractDefinitions DefinitionsCollection = new
ContractDefinitions();
DefinitionsCollection.Add(Host);
Contract.Definitions = DefinitionsCollection;


It doesn't help that this isn't the exact code - as:
* the field is named the same as the property (compile fail)
* minor typos (bracket, etc - compile fail)
* I would expect xsd.exe to output a getter only for a collection (is
this xsd.exe output?)

Marc
 
M

Morten Wennevik [C# MVP]

Ah, sorry Andy, my bad, you got the names and types right after all. I
somehow perceived it the other way around.

You most likely get the nullreference exception because the
ContractsDefinitions object is never created. You typicall do this in the
class constructor or inside the property

public Contracts()
{
Definitions = new ContractsDefinitions();
}

or

public ContractsDefinitions Definitions
{
get
{
if(this.Definitions == null)
this.Definitions = new ContractsDefinitions();
return this.Definitions;
}
set { this.Definitions = value; }
}


--
Happy Coding!
Morten Wennevik [C# MVP]


Morten Wennevik said:
Hi Andy,

You got the name and type switched.

private ContractDefinitions Definitions=null;

public ContractDefinitions Definitions
{
get { return this.Definitions; }
set {thisDefinitions=value; }
}

This is a ContractDefinitions object. The reference to the object and the
name of the property is called Definitions.

If you want a collection of Definitions objects try it the other way around

// Common naming uses lowercase version of the property name for the
// private placeholder.
// Adding _ in front of the name ensures it won't mix with property
// names in Intellisense.
private List<Definition> _definitions

public List<Definition> Definitions
{
get{ return _definitions; }
set{ _definitions = value; }
}

Now, if ContractDefinitions is a collection of Definitions just replace
List<Definition> with ContractDefinitions.

--
Happy Coding!
Morten Wennevik [C# MVP]


Andy B said:
I am trying to create a property of a class that holds a collection. Inside
the main class is a property that is defined as a collection. When I try to
assign values to it I keep getting all sorts of errors. The main one that I
get now is 'Can't convert Contracts.ContractModel.ContractDefinitions
collection to Contracts.ContractModel.Definition type'.

inside the main Contract class I have the Definitions collection property:

private ContractDefinitions Definitions=null;
public ContractDefinitions Definitions {
get { return this.Definitions; }
set {thisDefinitions=value; }
}
ContractDefinitions is the collection of Definition types. Here is what I
end up getting when I try to assign Definitions to the collection:

//Create a contract object. This works fine
Contract Contract = new Contract();

//create some definitions. This works as well...
Definition Host = new Definition);
Host.Word="Host";
Host.Definition1="A person who pays for and signs the contract";

//Assign the Definition to the collection class by creating it. These 2
lines give me a 'can't convert ContractDefinitions collection to Definition
type' error.
Contract.Definitions.Add(Host); //I get object reference set to a null
reference error//try it by creating an instance of the Deffinitions
collection
ContractDefinitions DefinitionsCollection = new ContractDefinitions();
DefinitionsCollection.Add(Host);

I also tried different ways as well but cant quite figure out how to do
this. The entire 20 class contract set was created from xsd file. Is there
any way I can get this to work?
 
A

Andy B

This is xsd output. Here is the schema code for the ContractDefinitions
collection:

<xs:element name="Contract">

<xs:complexType>

<xs:sequence>

<xs:element name="Definitions">

<xs:complexType>

<xs:sequence>

<xs:element name="Terms" type="Definition" />

</xs:sequence>

</xs:complexType>

</xs:element>


Something seems wrong with the code above for some reason and I can't put my
finger on it. It is supposed to be an element in an xml file called
Definitions (the "collection") representing up to an unlimited amount of
terms ("word/definition pairs"). So for example, when I want to searialize
the Contract class, the saved file (as far as the Definitions collection)
will look like this:

<Contract>
<Definitions>
<Term Word="Host" Definition="The person who pays for or signs this
contract" />
< !-- and so on with the Term element above -->
</Definitions>
< !-- and continuing on with other contract elements -->
</Contract>

I think possibly my design here messed up my output or something. Any advice
on how to fix it here? And I note that it should maybe be fixed here since
the below message says that the xsd output should have created the
collections by itself instead of me having to hand write it. Or did I not
understand that part?

Thanks for the help...
 
M

Marc Gravell

Can I check? Which is it that you know for sure?
* the C# code?
* the xsd schema?
* the desired xml layout?

If it is the latter, just write an xml file that looks about right,
and run it through xsd; it can generate an xsd from an xml source
(make sure to repeat anything that should be a collection). Likewise
xsd can generate C# from an xsd, but unfortunately it outputs arrays
instead of collections.
 
A

Andy B

I think I came up with the right way of doing this. This is the new and
reviced version of that section of the schema:

<xs:element name="Contract">

<xs:complexType>

<xs:sequence>

<xs:element name="Definitions">

<xs:complexType>

<xs:sequence>

<xs:element name="Terms" type="Definition" maxOccurs="unbounded" />

</xs:sequence>

</xs:complexType>

</xs:element>
 

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