Solved

retrieving Class object element by index

Posted on 2014-11-17
8
299 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 75

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 33

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 75

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 33

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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 75

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

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

919 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

22 Experts available now in Live!

Get 1:1 Help Now