C# naming objects on the fly

Discussion in 'Off Topic' started by Danja, Jun 15, 2010.

Thread Status:
Not open for further replies.
  1. Danja

    Danja Notebook Evangelist

    Reputations:
    57
    Messages:
    576
    Likes Received:
    0
    Trophy Points:
    30
    Hello,

    I'm trying to write a program that reads a file which contains 6 columns. For each row, it should store the value of columns 1, 2, and 4, and be able to cross-reference them when needed. Here is the code that I have written:

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    namespace NOEAssign
    {
        class Program
        {
            static void Main(string[] args)
            {
                string[] manip;
                string line = "";
    
                int counter = 1; //counter should go up to 6 and reset
                int entrycounter = 1; //streamreader should skip first 6 entries
                //string InputFileName = Console.ReadLine();
    
                //initializes objects and variables
                Residue resi1 = new Residue();
                Residue.Atom Atom1 = new Residue.Atom();
                string residuename = "";
                string AtomName = "";
                double shift = 0;
    
                //Parsing input file
                FileStream fs = File.Open(@"filepathgoeshere", FileMode.Open, FileAccess.Read);
                using (StreamReader sr = new StreamReader(fs))
                {
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (entrycounter > 1)
                        {
                            //handles line
                            manip = line.Split(' ');
                            foreach (string aline in manip)
                            {
                                bool hasvalue = CheckForEntry(aline);
                                if (hasvalue == true)
                                {
                                    if (counter == 1)
                                    {
                                        residuename = aline;
    
    
                                    }
                                    if (counter == 2)
                                    {
    
                                        AtomName = aline;
                                    }
    
                                    if (counter == 4)
                                    {
                                        shift = Convert.ToDouble(aline);
    
                                    }
                                    if (counter == 6)
                                    {
                                        resi1.ResiName = residuename;
                                        Atom1.name = AtomName;
                                        Atom1.Shift = shift;
    
                                        counter = 0;
                                        //Console.WriteLine("Residue is {0}, atom is {1}, shift is {2}", resi1.ResiName, Atom1.name, Atom1.Shift);
                                        //Console.ReadLine();
                                    }
    
                                    counter++;
                                }
                            }
                        }
                        else { }
                        entrycounter++;
                    }
                }
    
                //displays and diagnostics
                Console.WriteLine(resi1.ResiName);
                Console.WriteLine(Atom1.name);
                Console.WriteLine(Atom1.Shift);
                Console.ReadLine();
            }
            public class Residue
            {
                public string ResiName { get; set; }
    
                public class Atom
                {
                    public string name { get; set; }
                    public double Shift { get; set; }
    
                }
            }
    //I have a checkforentry function here
    }
    
    The problem is that the values read from the table constantly replace the variables in resi1 and atom1 rather than creating a new atom for every line and a new residue every time the residue name changes. Is there a way to make the program dynamically make a new object every time it is necessary?
     
  2. gdansk

    gdansk Notebook Deity

    Reputations:
    325
    Messages:
    728
    Likes Received:
    42
    Trophy Points:
    41
    Have you thought of using an array, or a collection (like an arraylist) and adding new objects to it as you need them?
     
  3. Danja

    Danja Notebook Evangelist

    Reputations:
    57
    Messages:
    576
    Likes Received:
    0
    Trophy Points:
    30

    An arraylist would be great, but how would I name it? Let's say I have the following data:

    Code:
        A12     BC3   4D   5.678  9.123      45
        A12     DE4   5F   6.789  1.234      56
        E67    FG89  12H  34.567  8.912       3
    
    I the program to run through not knowing how many lines it will read, but upon reading that data will create a residue object called A12 which contains two atom objects called BC3 and DE4. BC3 should contain a double = 5.678 and DE4 should contain a double = 6.789. Then, it should create a new class called E67, etc.

    I'm having trouble with the syntax to create an object with the given name. If possible, could you give me an example of how to do it?

    P.S. This is not homework, but it is academic in nature. I have two data tables with about 5000 entries each and I can either cross-reference them using a program, or I can do them manually!
     
  4. gdansk

    gdansk Notebook Deity

    Reputations:
    325
    Messages:
    728
    Likes Received:
    42
    Trophy Points:
    41
    A12 is a residue which contains a single atom? or can it contain multiple? (It looks like you want multiple).

    (I'm a Java programmer so this might be the wrong syntax but hopefully you understand the constructs I'm trying to use)
    Code:
            public class Atom
            {
                 public Atom(string name, double Shift)
                 {
                       this.name = name;
                       this.Shift = Shift;
                 }
                 public string name { get; set; }
                 public double Shift { get; set; }
            }
    
            public class Residue
            {
                //In Java it is necessary to initialize Lists in the constructor, I assume the same is true in C#
                public Residue()
                {
                      Atoms = new List<Atom>();
                }
                public string ResiName { get; set; }
                public List<Atom> Atoms { get; set; }
            }
    
    Then you can just add new atoms via "Atoms.Add(new Atom(name, Shift));" to a residue until the residue name changes... upon which you create a new residue.
     
  5. Danja

    Danja Notebook Evangelist

    Reputations:
    57
    Messages:
    576
    Likes Received:
    0
    Trophy Points:
    30
    Excellent! Thanks so much! Today happens to be my birthday and that code is a great present :D.
     
  6. Danja

    Danja Notebook Evangelist

    Reputations:
    57
    Messages:
    576
    Likes Received:
    0
    Trophy Points:
    30
    I'm still a little bit confused. Right now I have the following code snippet for when the reader reaches the last column:

    Code:
    if (counter == 6)
                                    {
                                        Residue CurrentResi = new Residue();
                                        CurrentResi.Atoms.Add(new Atom(AtomName, shift));
                                        Residues.Add(CurrentResi);
                                        counter = 0;
                                        //Console.WriteLine("Residue is {0}, atom is {1}, shift is {2}", resi1.ResiName, Atom1.name, Atom1.Shift);
                                        //Console.ReadLine();
                                    }
    
    When the residue is added to the list of residues, does it get a name within the list, or do I have to give it a string name attribute within the Residue class? If it does get a name within the list, can I manipulate that name to reflect the entry in the first column of the row?
     
  7. gdansk

    gdansk Notebook Deity

    Reputations:
    325
    Messages:
    728
    Likes Received:
    42
    Trophy Points:
    41
    Yes you're going to have to set "CurrentResi.name" to be whatever value it should be... or you could do this instead.

    Code:
        public class Residue
            {
                //In Java it is necessary to initialize Lists in the constructor, assume the same is true in C#
                public Residue(string name)
                {
                      ResiName = name;
                      Atoms = new List();
                }
                public string ResiName { get; set; }
                public List Atoms { get; set; }
            }
    
    and then in your code do this:
    Code:
    // Residue CurrentResi = new Residue();
    // Change that line to
    Residue CurrentResi = new Residue(CurrentResiName);
    
    Objects can have constructors that take any number of arguments... They can be created by creating a public function that returns nothing, the function must have the same name as the object. Inside of the constructor you should do things that are necessary for it to work. So if you pass the object a name, you should assign that value to its local name variable. I'd recommend reading this short example guide.
     
  8. swarmer

    swarmer beep beep

    Reputations:
    2,071
    Messages:
    5,234
    Likes Received:
    0
    Trophy Points:
    205
    Sorry I'm a little late to the party...

    Yes, and you are already creating new objects dynamically with these lines:

    Residue resi1 = new Residue();
    Residue.Atom Atom1 = new Residue.Atom();

    You just need to put that in your loop in order to create the new objects every time it's necessary.

    First, nothing ever has "a name within a list", because lists by definition are not indexed by name. Every item in a list has a position in the list -- 0, 1, 2, 3, etc. -- not a name.

    However, if you use a Hashtable instead of a List, then you can index by a name. See some examples on this page: C# Hashtable Use, Lookups and Examples
     
Thread Status:
Not open for further replies.

Share This Page