SITUATION:
I have a class "MainClass" that has an indexer "SubClass1Indexer".
This indexer returns an instance that implements a particular
interface "ISubClass1". This interface defines another indexer
"SubClass2Indexer". Bellow is some code with comments. It should
compile.

PROBLEM:
I would like to write something like this:

MainClass cm = new MainClass();
cm.SubClass1Values[0].SubClass2Values[0].ToString();

Note that "SubClass2Indexer" needs access to an internal field of
"SubClass1". This only seems to be possible if a field is allowed in
an interface, i.e. ISubClass1. That is not the case, though.

NONE IDEAL SOLUTIONS:
1) Make "this[]" in SubClass2Indexer aware of all the current and
future implementations of "ISubClass1".
2) Do a casting after "cm.SubClass1Values[0]" but then I have to write
separate indexers "SubClass2Indexer" for each implementation of
"ISubClass1".

QUESTION:
How can I solve the shortcomings in the above solutions? Or in general
how is this best handled?

CODE:
using System;
using System.Collections.Generic;
using System.Text;

namespace testProj
{
class Program
{
static void Main(string[] args)
{
MainClass cm = new MainClass();
cm.SubClass1Values[0].SubClass2Values[0].ToString();
}
}

//CLASSES
public class MainClass
{
private SubClass1Indexer m_subClass1Indexer;
protected internal List<ISubClass1> m_subClass1List; //
SubClass1Indexer needs access to this.

public SubClass1Indexer SubClass1Values
{
get { return m_subClass1Indexer; }
}
}

public class SubClass1 : ISubClass1
{
private SubClass2Indexer m_subClass2Indexer;
protected internal List<ISubClass2> m_subClass2List; //
SubClass2Indexer needs access to this.

public SubClass2Indexer SubClass2Values
{
get { return m_subClass2Indexer; }
}
}

//INTERFACES
public interface ISubClass1
{
//!!! If the following would be possible then in
SubClass2Indexer
// I would not have to make the function 'this[]' be aware of
all
// the ISubClass1 implementations.
//protected internal List<ISubClass> m_subClass2List;

SubClass2Indexer SubClass2Values { get; }
}

public interface ISubClass2
{
}

//INDEXERS
public class SubClass1Indexer
{
private readonly MainClass m_subClass1Owner;

public SubClass1Indexer(MainClass seriesOwner)
{
m_subClass1Owner = seriesOwner;
}

public ISubClass1 this[Int32 index]
{
get {
return m_subClass1Owner.m_subClass1List[index];
}
}
}

public class SubClass2Indexer
{
private readonly ISubClass1 m_subClass2Owner;

public SubClass2Indexer(ISubClass1 subClass2Owner)
{
m_subClass2Owner = subClass2Owner;
}

public ISubClass2 this[Int32 index]
{
//The command commented out would be possible if one could
// define a field in an interface. Now I'll need a switch
// to handle all the IClass1 implementations. So I can't
just
// add a new implementation without adjusting this
function.
//get { return m_subClass2Owner.m_subClass2List[index]; }
get { return
((SubClass1)m_subClass2Owner).m_subClass2List[index]; }
}
}
}

RE: Fields in Interfaces, Indexer by CiaranODonnell

CiaranODonnell
Fri Feb 16 06:57:07 CST 2007

Your structure is confusing which means there may be a simpler design.
However, I think you should be able to solve the issue by giving
SubClass1Indexer a constructor that took a List<ISubClass1> rather than a
MainClass.

Post again if this doesnt work out.

--
Ciaran O''Donnell
http://wannabedeveloper.spaces.live.com


"hufaunder@yahoo.com" wrote:

> SITUATION:
> I have a class "MainClass" that has an indexer "SubClass1Indexer".
> This indexer returns an instance that implements a particular
> interface "ISubClass1". This interface defines another indexer
> "SubClass2Indexer". Bellow is some code with comments. It should
> compile.
>
> PROBLEM:
> I would like to write something like this:
>
> MainClass cm = new MainClass();
> cm.SubClass1Values[0].SubClass2Values[0].ToString();
>
> Note that "SubClass2Indexer" needs access to an internal field of
> "SubClass1". This only seems to be possible if a field is allowed in
> an interface, i.e. ISubClass1. That is not the case, though.
>
> NONE IDEAL SOLUTIONS:
> 1) Make "this[]" in SubClass2Indexer aware of all the current and
> future implementations of "ISubClass1".
> 2) Do a casting after "cm.SubClass1Values[0]" but then I have to write
> separate indexers "SubClass2Indexer" for each implementation of
> "ISubClass1".
>
> QUESTION:
> How can I solve the shortcomings in the above solutions? Or in general
> how is this best handled?
>
> CODE:
> using System;
> using System.Collections.Generic;
> using System.Text;
>
> namespace testProj
> {
> class Program
> {
> static void Main(string[] args)
> {
> MainClass cm = new MainClass();
> cm.SubClass1Values[0].SubClass2Values[0].ToString();
> }
> }
>
> //CLASSES
> public class MainClass
> {
> private SubClass1Indexer m_subClass1Indexer;
> protected internal List<ISubClass1> m_subClass1List; //
> SubClass1Indexer needs access to this.
>
> public SubClass1Indexer SubClass1Values
> {
> get { return m_subClass1Indexer; }
> }
> }
>
> public class SubClass1 : ISubClass1
> {
> private SubClass2Indexer m_subClass2Indexer;
> protected internal List<ISubClass2> m_subClass2List; //
> SubClass2Indexer needs access to this.
>
> public SubClass2Indexer SubClass2Values
> {
> get { return m_subClass2Indexer; }
> }
> }
>
> //INTERFACES
> public interface ISubClass1
> {
> //!!! If the following would be possible then in
> SubClass2Indexer
> // I would not have to make the function 'this[]' be aware of
> all
> // the ISubClass1 implementations.
> //protected internal List<ISubClass> m_subClass2List;
>
> SubClass2Indexer SubClass2Values { get; }
> }
>
> public interface ISubClass2
> {
> }
>
> //INDEXERS
> public class SubClass1Indexer
> {
> private readonly MainClass m_subClass1Owner;
>
> public SubClass1Indexer(MainClass seriesOwner)
> {
> m_subClass1Owner = seriesOwner;
> }
>
> public ISubClass1 this[Int32 index]
> {
> get {
> return m_subClass1Owner.m_subClass1List[index];
> }
> }
> }
>
> public class SubClass2Indexer
> {
> private readonly ISubClass1 m_subClass2Owner;
>
> public SubClass2Indexer(ISubClass1 subClass2Owner)
> {
> m_subClass2Owner = subClass2Owner;
> }
>
> public ISubClass2 this[Int32 index]
> {
> //The command commented out would be possible if one could
> // define a field in an interface. Now I'll need a switch
> // to handle all the IClass1 implementations. So I can't
> just
> // add a new implementation without adjusting this
> function.
> //get { return m_subClass2Owner.m_subClass2List[index]; }
> get { return
> ((SubClass1)m_subClass2Owner).m_subClass2List[index]; }
> }
> }
> }
>
>

Re: Fields in Interfaces, Indexer by hufaunder

hufaunder
Fri Feb 16 11:07:58 CST 2007

Ciaran,

That indeed seems to be a solution. The reason I was passing MainClass
to the ctr of SubClass1Indexer is because samples from MSDN and
CodeProject both did it this way. See here:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcwlkIndexedPropertiesTutorial.asp

Class WordCollection is the indexer and it's constructor takes the
parent class Document. MSDN says: "For each "indexed property," you
define a nested class, which contains a reference back to the main
class instance."

Is there a reason why most people do it this way and not the way you
suggested (which seems to work better for me)?