Autor Beitrag
winx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 249



BeitragVerfasst: Do 15.12.05 17:08 
Hi,

ich habe folgendes Problem:

Ich habe 3 Interfaces die wie folht aussehen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
ISuper

IChild1 : ISuper

IChild2 : ISuper

Nun habe ich eine Klasse die eine Liste der ISuper Objekte enthält
ausblenden C#-Quelltext
1:
public void getNumber(list<ISuper>)...					


Ist es mir irgendwie möglich diese Funktion durch übergeben mit einer Liste der IChild1 oder IChild2 Objekte aufzurufen
sprich
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
void test
{
   ...
   list<IChild1> liste = new list<IChild1>;
   obj.getNumber(liste);

}


Irgendwie müsste jedes Elemet casten lassen...ist dies auch automatisch möglich, da ja das Interface
IChild1 die Schnitstelle ISuper besitzt???

Danke
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Do 15.12.05 18:37 
Nein, das geht so nicht. List<ISuper> und List<IChild1> haben keine Vererbungsbeziehung (auch wenn es zwischen ISuper und IChild1 einegibt), da C# nur F-gebundene Generizität unterstützt.

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Robert_G
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 416


Delphi32 (D2005 PE); Chrome/C# (VS2003 E/A, VS2005)
BeitragVerfasst: Do 15.12.05 22:57 
user profile iconwinx hat folgendes geschrieben:
Irgendwie müsste jedes Elemet casten lassen...ist dies auch automatisch möglich, da ja das Interface
IChild1 die Schnitstelle ISuper besitzt???
Nein.
List<IChild> erbt ja nicht von List<ISuper> (Wie Motzi bereits schrieb)

Es gibt sicher 5.000 Möglichkeiten dafür, ich habe mal ein paar Bleistifte runtergetippt. Vllt hilft's dir.

Falls GetNumber[meta]dumm benannt btw, da ein void nie GetXXX heißen sollte[/meta] wirklich einen Eintrag anhand einer Nummer finden sollte, wäre hier eines der Dictionaries das Mittel der Wahl. ;)


ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
interface ISuper
{
  int Id { get;}
}

interface IChild : ISuper
{
  string Name { get;}
}

class Super : ISuper
{
  int id;

  public int Id
  {
    get { return id; }
  }

  public Super(int id)
  {
    this.id = id;
  }

  public static TReturn FindById<TInput, TReturn>(IEnumerable<TInput> list, int id)
    where TInput  : ISuper
    where TReturn : TInput
  {
    foreach (TInput item in list)
    {
      if (item is TReturn && id.Equals(item.Id))
      {
        return (TReturn)(item);
      }
    }
    return default(TReturn);
  }
}

class Child : Super, IChild
{
  string name;

  public string Name
  {
    get { return name; }
    set { name = value; }
  }

  public Child(int id, string name)
    : base(id)
  {
    this.name = name;
  }
}

class Decorator<TInput, TReturn> : IEnumerable<TReturn>
where TReturn : TInput
{
  readonly IEnumerable<TInput> innerInstance;

  protected IEnumerable<TInput> InnerInstance
  {
    get { return innerInstance; }
  }

  public Decorator(IEnumerable<TInput> innerInstance)
  {
    this.innerInstance = innerInstance;
  }

  #region IEnumerable<T> Members

  public IEnumerator<TReturn> GetEnumerator()
  {
    foreach (TInput item in innerInstance)
    {
      if (item is TReturn)
        yield return (TReturn)item;
    }
  }

  #endregion

  #region IEnumerable Members

  IEnumerator IEnumerable.GetEnumerator()
  {
    return innerInstance.GetEnumerator();
  }

  #endregion
}



class Program
{
  static void Main(string[] args)
  {
    List<ISuper> list = new List<ISuper>();

    for (int i = 0; i < 10; i++)
    {
      list.Add(new Super(i));
      list.Add(new Child(i, i.ToString()));
    }

    int searchId = 2;

    IChild child;

    // cast auf IChild
    child = (IChild)list.Find(delegate(ISuper item)
                                      {
                                        return item is IChild &&
                                               item.Id == searchId;
                                      });

    // generic Method in deiner Klasse
    child = Super.FindById<ISuper, IChild>(list, 2);

    // Kopie des Containers, typisiert auf IChild
    List<IChild> childList = list.ConvertAll<IChild>(delegate(ISuper input)
                                                             {
                                                               if (input is IChild)
                                                                 return (IChild)input;
                                                               else
                                                                 return null;
                                                             });


    child = childList.Find(delegate(IChild item)
                                    {
                                      return item != null &&
                                             item.Id == searchId &&
                                             item.Name == searchId.ToString();
                                    });

    // Ein Dekorator, der dir eine auf IChild gefilterte Ansicht gibt
    Decorator<ISuper, IChild> childDecorator = new Decorator<ISuper, IChild>(list);

    foreach (IChild item in childDecorator)
    {
      Console.WriteLine(item.Name);
    }
  }
}