Fields in Interfaces, Indexer

H

hufaunder

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]; }
}
}
}
 
G

Guest

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


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]; }
}
}
}
 
H

hufaunder

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/d...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)?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top