Solved

retrieving Class object element by index

Posted on 2014-11-17
8
288 Views
Last Modified: 2014-11-22
Hi,
if I have a class such as Test below and I create a new instance Test T = new Test();  How can I now reference object T by index. For instance if I want to place the value of T into a comma delimited string I could do the following

string Str = T.fld1+","+T.fld2+","+T.fld3+","+T.fld4


However I would like to be able to do something like this

for(int x=0;x<=4;x++)
{
Str=T[ x ]+","
}


Is there a way to do this ?

regards
Pat

    public class Test
    {
        public string fld1 { get; set; }
        public string fld2 { get; set; }
        public string fld3 { get; set; }
        public string fld4 { get; set; }
  public Test()
  {
fld1="test1";
fld2="test2";
fld3="test3";
fld4="test4";
  }  
}
0
Comment
Question by:pclarke7
8 Comments
 
LVL 74

Accepted Solution

by:
käµfm³d   👽 earned 167 total points
ID: 40448615
You could implement the index operator on your class:

public class Test
{
    public string fld1 { get; set; }
    public string fld2 { get; set; }
    public string fld3 { get; set; }
    public string fld4 { get; set; }
    public Test()
    {
        fld1 = "test1";
        fld2 = "test2";
        fld3 = "test3";
        fld4 = "test4";
    }

    public string this[int index]
    {
        get
        {
            switch (index)
            {
                case 1:
                    return this.fld1;
                case 2:
                    return this.fld2;
                case 3:
                    return this.fld3;
                case 4:
                    return this.fld4;
                default:
                    throw new IndexOutOfRangeException("Invalid field index.");

            }
        }
    }

Open in new window


Just be careful, as this is a brittle design, and it leads to multiple places that have to be edited in the event of (applicable) changes.
0
 
LVL 32

Assisted Solution

by:it_saige
it_saige earned 167 total points
ID: 40448616
Perhaps something like:
using System;
using System.Linq;

namespace EE_Q28564134
{
	class Test
	{
		public string Field1 { get; set; }
		public string Field2 { get; set; }
		public string Field3 { get; set; }
		public string Field4 { get; set; }

		public Test()
		{
			Field1 = "test1";
			Field2 = "test2";
			Field3 = "test3";
			Field4 = "test4";
		}

		public string this[int i]
		{
			get { return (from field in typeof(Test).GetProperties() where field.Name.Equals(string.Format("Field{0}", i)) select (string)field.GetValue(this, null)).FirstOrDefault(); }
			set { (from field in typeof(Test).GetProperties() where field.Name.Equals(string.Format("Field{0}", i)) select field).FirstOrDefault().SetValue(this, value, null); }
		}
	}

	class Program
	{
		static void Main(string[] args)
		{
			Test tst = new Test();
			string str = string.Empty;
			for (int i = 0; i < 4; i++)
				str = string.Format("{0}{1}+,", str, tst[i + 1]);

			Console.WriteLine(str);
			Console.ReadLine();
		}
	}
}

Open in new window


Produces the following output:Capture.JPG
Echoing Kaufmed's warning.

-saige-
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 167 total points
ID: 40448623
If you go with it_saige's solution--which is the same solution, but with added Reflection to make the code more dynamic--be sure to add appropriate error checking in. For instance, if you were to pass the value 5 to the index, his solution would return null. But does null mean that the value itself is null or that the property does not exist?
0
 
LVL 32

Assisted Solution

by:it_saige
it_saige earned 167 total points
ID: 40448660
@kaufmed, mine is only posted after yours because you were quicker.  I was still working on mine.  I feel like the slow kid taking the test in class.  LOL

But kaufmed is correct.  Mine is essentially the same as his with the exception of being more dynamic but will return null (since a default string is a null value) in cases where the index is out of bounds (so to speak).

Example -
using System;
using System.Linq;

namespace EE_Q28564134
{
	class Test
	{
		public string Field1 { get; set; }
		public string Field2 { get; set; }
		public string Field3 { get; set; }
		public string Field4 { get; set; }

		public Test()
		{
			Field1 = "test1";
			Field2 = "test2";
			Field3 = "test3";
			Field4 = "test4";
		}

		public string this[int i]
		{
			get { return (from field in typeof(Test).GetProperties() where field.Name.Equals(string.Format("Field{0}", i)) select (string)field.GetValue(this, null)).FirstOrDefault(); }
			set { (from field in typeof(Test).GetProperties() where field.Name.Equals(string.Format("Field{0}", i)) select field).FirstOrDefault().SetValue(this, value, null); }
		}
	}

	class Program
	{
		static void Main(string[] args)
		{
			Test tst = new Test();
			string str = string.Empty;
			Console.WriteLine("This works");
			for (int i = 0; i < 4; i++)
				str = string.Format("{0}{1}+,", str, tst[i + 1]);
			Console.WriteLine(str);

			Console.WriteLine();
			str = string.Empty;

			Console.WriteLine("Added error checking and forced an error");
			for (int i = 0; i < 5; i++)
				str = string.Format("{0}{1}+,", str, !string.IsNullOrEmpty(tst[i + 1]) ? tst[i + 1] : string.Format("Field or value for Test{0}; does not exist", i + 1));
			Console.WriteLine(str);

			Console.WriteLine();
			str = string.Empty;

			Console.WriteLine("Now lets really get wild");
			tst[1] = "Changed1";
			tst[2] = "Changed2";
			tst[3] = "Changed3";
			// Forcing an error
			try { tst[5] = "Changed5"; }
			catch (Exception) { Console.WriteLine("Oops, you can't do that"); }
			Console.WriteLine();

			for (int i = 0; i < 5; i++)
				str = string.Format("{0}{1}+,", str, !string.IsNullOrEmpty(tst[i + 1]) ? tst[i + 1] : string.Format("Field or value for Test{0}; does not exist", i + 1));
			Console.WriteLine(str);
			Console.ReadLine();
		}
	}
}

Open in new window


Now produces the following output:Capture.JPG
-saige-
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 40448668
; )
0
 
LVL 40

Assisted Solution

by:Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger) earned 83 total points
ID: 40449126
Personally, I would have designed the class so that these fields are an array. It would then be very easy to look through them. It would also enable you to easily add new fields later on without causing problems with existing applications.
0
 
LVL 18

Assisted Solution

by:Richard Lee
Richard Lee earned 83 total points
ID: 40449336
I would firstly reevaluate why you wish to take this approach. If you wish to access the properties by an index I would suggest using a collection based approach.

If you expand on your requirements then I believe a better approach could be provided. While the code samples above solve your problem, as highlighted these approached are prone to bugs creeping into your application. I would warn that spend some time to evaluate your requirements and come up with a better architectural approach as opposed to a quick hack.

public string[] Field { get; set; }

Open in new window


This code would be way more resilient in the long run. I offer credit to @Jacques Bourgeois as he suggested this before I even viewed the question. I simply elaborate and stress, since I have been down this path many times. There is no compromise for good architectural designs.
0
 

Author Closing Comment

by:pclarke7
ID: 40459490
Thanks to all for your comments. Index operator is exactly what I was looking for and the various implementations of it were great to see. I don't think that there are any design issues here as the data that I am trying to access by index is not related in such a way that i should be placed into an array. I just happen to have a lot of data that can be accessed easier and cleaner by index. I am a big fan of  strongly typed data however there are times when accessing this data is best done by index.

regards
Pat
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Introduction Hi all and welcome to my first article on Experts Exchange. A while ago, someone asked me if i could do some tutorials on object oriented programming. I decided to do them on C#. Now you may ask me, why's that? Well, one of the re…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now