p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   ASP.NET 3.5 Basics (http://p2p.wrox.com/forumdisplay.php?f=351)
-   -   Adding generic data to a class (http://p2p.wrox.com/showthread.php?t=80662)

chroniclemaster1 August 24th, 2010 06:19 PM

Adding generic data to a class
 
I'm having a couple basic generics problems. Basically, I'm trying to identify a piece of content by two indexes.

1) I need to store the content in the class, so I need to create a class variable, classTableCellContent, to store it in. Therefore I need to create one, requiring me to constrain the generic type "where ContentType : new()". However, when I attempt to consume this type with a string, e.g. TableCell<string>, it throws a compiler error "The type 'string' must have a public parameterless constructor in order to use it as a parameter blahblahblah..."

2) I need to accept input, so I have an add function. However, when I try to indicate that the third parameter is the same data type, i.e. ContentType, the compiler seems to believe that I'm creating a "new" data type with a poorly chosen name that hides the original data type declared in the class declaration. I'm sure this must be something stupid I'm missing. All I want to do is accept an input variable of the generic type in a function and store it in the class for later use.

Here's the code. I've highlighted the lines that seem to be throwing the errors.

Code:

public class TableCell<ContentType> where ContentType : new()
    {
        private int classRowIndex = 0;
        private int classColumnIndex = 0;
      private ContentType classTableCellContent = new ContentType();
       
       
        /// <summary>
        /// TableCell<ContentType>() - Constructors for creating a new TableCell
        /// </summary>
        public TableCell() {}
        public TableCell(int inputRowIndex, int inputColumnIndex, ContentType inputTableCellContent)
        {
            addContent<ContentType>(inputRowIndex, inputColumnIndex, inputTableCellContent);
        }
       
       
        /// <summary>
        /// void addContent<ContentType>(int inputRowIndex, int inputColumnIndex, ContentType inputTableCellContent) - accepts row and column indexesa dictionary and returns the XHTML to display all it's contents as a list
        /// </summary>
        public void addContent<ContentType>(int inputRowIndex, int inputColumnIndex, ContentType inputTableCellContent)
        {
            classRowIndex = inputRowIndex;
            classColumnIndex = inputColumnIndex;
            classTableCellContent = inputTableCellContent;
        }
    }


samjudson August 25th, 2010 03:39 AM

Well you're main problem is that you can't type the following code:

string s = new string();

As there is no constructor for string that takes no parameters.

It may be that you simply remove the " = new ContentType()" from the variable declaration. If you use that variable you will have to check to see if it is null, but other than that you shouldn't have any problems.

Also, it is convention to use "T" as the name of the generic type - this is much shorter and easier to read, and also makes it easier to spot where the generic type is used. ContentType could quite easily be the name of an actual class.

sridhar c August 25th, 2010 05:25 AM

Response:To Generic Data usage error
 
Hi Chroniclemaster1, There is an error your code, which throws cannot implicitly convert type ContentType to ContentType ....
Just remove the '<ContentType>' content in addContent method and should compile fine.
The error free code is as follows:
public class TableCell<ContentType> where ContentType : new()
{
private int classRowIndex = 0;
private int classColumnIndex = 0;
private ContentType classTableCellContent = new ContentType();


/// <summary>
/// TableCell<ContentType>() - Constructors for creating a new TableCell
/// </summary>
public TableCell() { }
public TableCell(int inputRowIndex, int inputColumnIndex, ContentType inputTableCellContent)
{
addContent(inputRowIndex, inputColumnIndex, inputTableCellContent);
}


/// <summary>
/// void addContent<ContentType>(int inputRowIndex, int inputColumnIndex, ContentType inputTableCellContent) - accepts row and column indexesa dictionary and returns the XHTML to display all it's contents as a list
/// </summary>
public void addContent(int inputRowIndex, int inputColumnIndex, ContentType inputTableCellContent)
{
classRowIndex = inputRowIndex;
classColumnIndex = inputColumnIndex;
this.classTableCellContent = inputTableCellContent;
}
}

Hope it solves your problem.
Bye
sridhar

sridhar c August 25th, 2010 05:45 AM

Generic data var
 
Hi ChronicleMaster1,
What judson says is right, and apart from what i posted (corrected addContent declaration) additionally remove the new constraint.
It should work!
Good luck.

chroniclemaster1 August 25th, 2010 12:57 PM

Quote:

Originally Posted by samjudson (Post 262376)
It may be that you simply remove the " = new ContentType()" from the variable declaration.

:) Got it! I'm no longer simply a consumer of generics, I'm now an author. The string problem was exactly what you pointed out Sam. Since the variable is an open generic type, I can't initialize it (like consuming an interface). Once I dropped the initialization "ContentType classTableCellContent;" that problem went away.

Quote:

Originally Posted by sridhar c (Post 262379)
Hi Chroniclemaster1, There is an error your code, which throws cannot implicitly convert type ContentType to ContentType ....
Just remove the '<ContentType>' content in addContent method and should compile fine.

Then sridhar c's fix solved my problem with the second type declaration. Now I only declare one open data type so the function is talking the same set of variable names as the class. :D

Quote:

Originally Posted by samjudson (Post 262376)
Also, it is convention to use "T" as the name of the generic type - this is much shorter and easier to read, and also makes it easier to spot where the generic type is used. ContentType could quite easily be the name of an actual class.

:) I tried changing the names on my variable types several times during testing so "ContentType" was simply the last one I'd used. I've now changed it back to my preferred TContent (using a T prefix like the very sensible "I" prefix used for interfaces). I like T because it clearly stands for type, but the typical usage for multiple types (T, U, V) seems a bit silly to me since U and V are only weakly related to the idea of type (their letters are adjacent to T which stands for type). I also have to waste brain space remembering that this T and U in one function are totally unrelated to T and U in another function / class. Using interface style naming with a T prefix like TContent greatly reduces naming collisions. This isn't entirely customary but the consistent use of T (and the variables appearance in brackets <TContent>) still make it clear for anyone that these are open generic type names. So that's what I actually use and why I prefer it.


All times are GMT -4. The time now is 01:28 PM.

Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.