gratifiant > microsoft.* > microsoft.dotnet.csharp

bart s. (30/11/2004, 20h52)
bjr,

y a t-il un moyen de specifier le type d'objet contenu dans un ArrayList (ou
un autre objet) ?

exemple:
public ArrayList toto()
{
ArrayList a = new ArrayList();

for(int i=0; i < 10;i++) a.Add(new String("toto"));
return a;
}
....
{
ArrayList a;
String b;

a = toto();
b=((Mot)a[0]).ToLower();
}

obligation de caster les objets utilisés, cela me semble moyen pour un
langage qui se veut typé.

merci
Ambassadeur Kosh (30/11/2004, 22h37)
on arrete pas de le dire : pas de ArrayList.
passer à 2005 et generics, ou generer ses classes en utilisant ce modele la
en 2003 :

using System;
using System.Collections;

namespace Test
{
/// <summary>
/// A collection that stores <see cref='Dummy'/> objects.
/// </summary>
[Serializable()]
public class DummyCollection : CollectionBase {

/// <summary>
/// Initializes a new instance of <see cref='DummyCollection'/>.
/// </summary>
public DummyCollection()
{
}

/// <summary>
/// Initializes a new instance of <see cref='DummyCollection'/> based on
another <see cref='DummyCollection'/>.
/// </summary>
/// <param name='val'>
/// A <see cref='DummyCollection'/> from which the contents are copied
/// </param>
public DummyCollection(DummyCollection val)
{
this.AddRange(val);
}

/// <summary>
/// Initializes a new instance of <see cref='DummyCollection'/>
containing any array of <see cref='Dummy'/> objects.
/// </summary>
/// <param name='val'>
/// A array of <see cref='Dummy'/> objects with which to intialize
the collection
/// </param>
public DummyCollection(Dummy[] val)
{
this.AddRange(val);
}

/// <summary>
/// Represents the entry at the specified index of the <see
cref='Dummy'/>.
/// </summary>
/// <param name='index'>The zero-based index of the entry to locate in the
collection.</param>
/// <value>The entry at the specified index of the collection.</value>
/// <exception cref='ArgumentOutOfRangeException'><paramref name='index'/>
is outside the valid range of indexes for the collection.</exception>
public Dummy this[int index] {
get {
return ((Dummy)(List[index]));
}
set {
List[index] = value;
}
}

/// <summary>
/// Adds a <see cref='Dummy'/> with the specified value to the
/// <see cref='DummyCollection'/>.
/// </summary>
/// <param name='val'>The <see cref='Dummy'/> to add.</param>
/// <returns>The index at which the new element was inserted.</returns>
/// <seealso cref='DummyCollection.AddRange'/>
public int Add(Dummy val)
{
return List.Add(val);
}

/// <summary>
/// Copies the elements of an array to the end of the <see
cref='DummyCollection'/>.
/// </summary>
/// <param name='val'>
/// An array of type <see cref='Dummy'/> containing the objects to add
to the collection.
/// </param>
/// <seealso cref='DummyCollection.Add'/>
public void AddRange(Dummy[] val)
{
for (int i = 0; i < val.Length; i++) {
this.Add(val[i]);
}
}

/// <summary>
/// Adds the contents of another <see cref='DummyCollection'/> to the
end of the collection.
/// </summary>
/// <param name='val'>
/// A <see cref='DummyCollection'/> containing the objects to add to
the collection.
/// </param>
/// <seealso cref='DummyCollection.Add'/>
public void AddRange(DummyCollection val)
{
for (int i = 0; i < val.Count; i++)
{
this.Add(val[i]);
}
}

/// <summary>
/// Gets a value indicating whether the
/// <see cref='DummyCollection'/> contains the specified <see
cref='Dummy'/>.
/// </summary>
/// <param name='val'>The <see cref='Dummy'/> to locate.</param>
/// <returns>
/// <see langword='true'/> if the <see cref='Dummy'/> is contained in the
collection;
/// otherwise, <see langword='false'/>.
/// </returns>
/// <seealso cref='DummyCollection.IndexOf'/>
public bool Contains(Dummy val)
{
return List.Contains(val);
}

/// <summary>
/// Copies the <see cref='DummyCollection'/> values to a one-dimensional
<see cref='Array'/> instance at the
/// specified index.
/// </summary>
/// <param name='array'>The one-dimensional <see cref='Array'/> that is
the destination of the values copied from <see
cref='DummyCollection'/>.</param>
/// <param name='index'>The index in <paramref name='array'/> where
copying begins.</param>
/// <exception cref='ArgumentException'>
/// <para><paramref name='array'/> is multidimensional.</para>
/// <para>-or-</para>
/// <para>The number of elements in the <see cref='DummyCollection'/> is
greater than
/// the available space between <paramref name='arrayIndex'/> and
the end of
/// <paramref name='array'/>.</para>
/// </exception>
/// <exception cref='ArgumentNullException'><paramref name='array'/> is
<see langword='null'/>. </exception>
/// <exception cref='ArgumentOutOfRangeException'><paramref
name='arrayIndex'/> is less than <paramref name='array'/>'s lowbound.
</exception>
/// <seealso cref='Array'/>
public void CopyTo(Dummy[] array, int index)
{
List.CopyTo(array, index);
}

/// <summary>
/// Returns the index of a <see cref='Dummy'/> in
/// the <see cref='DummyCollection'/>.
/// </summary>
/// <param name='val'>The <see cref='Dummy'/> to locate.</param>
/// <returns>
/// The index of the <see cref='Dummy'/> of <paramref name='val'/> in
the
/// <see cref='DummyCollection'/>, if found; otherwise, -1.
/// </returns>
/// <seealso cref='DummyCollection.Contains'/>
public int IndexOf(Dummy val)
{
return List.IndexOf(val);
}

/// <summary>
/// Inserts a <see cref='Dummy'/> into the <see cref='DummyCollection'/>
at the specified index.
/// </summary>
/// <param name='index'>The zero-based index where <paramref name='val'/>
should be inserted.</param>
/// <param name='val'>The <see cref='Dummy'/> to insert.</param>
/// <seealso cref='DummyCollection.Add'/>
public void Insert(int index, Dummy val)
{
List.Insert(index, val);
}

/// <summary>
/// Returns an enumerator that can iterate through the <see
cref='DummyCollection'/>.
/// </summary>
/// <seealso cref='IEnumerator'/>
public new DummyEnumerator GetEnumerator()
{
return new DummyEnumerator(this);
}

/// <summary>
/// Removes a specific <see cref='Dummy'/> from the <see
cref='DummyCollection'/>.
/// </summary>
/// <param name='val'>The <see cref='Dummy'/> to remove from the <see
cref='DummyCollection'/>.</param>
/// <exception cref='ArgumentException'><paramref name='val'/> is not
found in the Collection.</exception>
public void Remove(Dummy val)
{
List.Remove(val);
}

/// <summary>
/// Enumerator that can iterate through a DummyCollection.
/// </summary>
/// <seealso cref='IEnumerator'/>
/// <seealso cref='DummyCollection'/>
/// <seealso cref='Dummy'/>
public class DummyEnumerator : IEnumerator
{
IEnumerator baseEnumerator;
IEnumerable temp;

/// <summary>
/// Initializes a new instance of <see cref='DummyEnumerator'/>.
/// </summary>
public DummyEnumerator(DummyCollection mappings)
{
this.temp = ((IEnumerable)(mappings));
this.baseEnumerator = temp.GetEnumerator();
}

/// <summary>
/// Gets the current <see cref='Dummy'/> in the <seealso
cref='DummyCollection'/>.
/// </summary>
public Dummy Current {
get {
return ((Dummy)(baseEnumerator.Current));
}
}

object IEnumerator.Current {
get {
return baseEnumerator.Current;
}
}

/// <summary>
/// Advances the enumerator to the next <see cref='Dummy'/> of the <see
cref='DummyCollection'/>.
/// </summary>
public bool MoveNext()
{
return baseEnumerator.MoveNext();
}

/// <summary>
/// Sets the enumerator to its initial position, which is before the
first element in the <see cref='DummyCollection'/>.
/// </summary>
public void Reset()
{
baseEnumerator.Reset();
}
}
}
}
Mitsuru FURUTA [Ms] (01/12/2004, 00h03)
Bonjour, restons calmes...

Ce que vous dites est vrai mais qui d'autre qu'un langage typé peut offrir
une liste universelle basée sur un ancètre commun à tous ? :-)
Sérieusement, en attendant les générics du framework 2, vous pouvez toujours
réécrire l'indexeur de l'ArrayList, mais quoi qu'il arrive il vous faudra
réécrire une nouvelle classe si vous voulez éviter les casts puisque comme
vous l'avez dit, tout est typé.

public class myarray : ArrayList
{
public new string this[int index]
{
get
{
return (string) base[index];
}
set
{
base[index] = value;
}
}
}

Bonne continuation,

Mitsuru FURUTA [Microsoft FRANCE]

"Ambassadeur Kosh" <kosh.naranek> wrote in message
news:1404
[..]
Ambassadeur Kosh (01/12/2004, 00h26)
> Ce que vous dites est vrai mais qui d'autre qu'un langage typé peut offrir
> une liste universelle basée sur un ancètre commun à tous ? :-)


loin de moi l'idée de reprocher des choses au langage.

il y'a juste que ce code passe sur ce forum une fois par semaine, et que
c'est un peu lourd...
que dire d'autre sinon qu'installer codesmith lui permettra d'éviter de se
refaire un générateur...

pour ma part, je bosse en 2.0 depuis quelques temps, et c'est un vrai
bonheur.
vivement que les autres puissent en profiter aussi.
Sylvain Lafontaine (01/12/2004, 01h06)
J'ai un peu de la difficulté à comprendre votre point de vue. Les langages
typés exigent que le programmeur précisent exactement le fond de sa pensée,
ceci afin d'éviter le plus possibles les erreurs. Par exemple, Javascript
est beaucoup moins typé que C#, de sorte que vous n'avez pas besoin d'écrire
le casting mais cela ouvre aussi la porte à plusieurs nouvelles sources
d'erreurs possibles.

En plus de la notion de template et de classe dérivée mentionnées dans les
réponses précédentes, vous pouvez également utiliser les fonctions
virtuelles, les « delegate » ainsi que la fonction .GetType(), sans compter
les mécanismes de « Reflexion », pour parfaire ce genre de code.

S. L.

En plus des messages précédents, vous
"bart s." <gachna_annti_spam> wrote in message
news:15ce
[..]
cyrille (01/12/2004, 12h53)
In article <uGC84Ez1EHA.3324>, "Sylvain Lafontaine"
<sylvain aei ca (fill the blanks, no spam please)> says...
> En plus de la notion de template et de classe dérivée mentionnées dans les
> réponses précédentes, vous pouvez également utiliser les fonctions
> virtuelles, les « delegate » ainsi que la fonction .GetType(), sans compter
> les mécanismes de « Reflexion », pour parfaire ce genre de code.


J'ajouterais à ce sujet que c'est une façon de pensée qui fonctionne bien quand
on n'a pas à ce soucier des performances.
Pour gagner en performance lors du runtime, il vaut mieux déléguer au
compilateur le plus de chose possible, comme la vérification des types.
Des boucles sur des centaines de lignes que l'on exécute souvent font largement
la différences entre les deux approches ;o)

bonne route,
cyrille
Ambassadeur Kosh (01/12/2004, 15h58)
> J'ajouterais à ce sujet que c'est une façon de penser qui fonctionne bien quand
> on n'a pas à ce soucier des performances.
> Pour gagner en performance lors du runtime, il vaut mieux déléguer au
> compilateur le plus de chose possible, comme la vérification des types.
> Des boucles sur des centaines de lignes que l'on exécute souvent font largement
> la différences entre les deux approches ;o)


je suis de l'avi de cyrille. la résolution de type "statique" est vertueuse.
on sait à la compilation ou sont les problemes.
le but du jeu, c'est quand meme de faire en sorte que ce qui est juste
compile et que ce qui est faux ne compile pas.
ça a les avantages d'une preuve, et en plus, le resultat est efficace...

maintenant, l'approche dynamique offre des énormes possibilités, mais bon...
quel interet de faire un Dictionary qui accepte des Chien pendant 20 minutes
et qui une fois vide, n'accepte plus que des Chat. meme si ça en a un, le
vehicule de la contrainte est il vraiment le Dictionary ? et n'y a t'il pas
quelque chose qui cloche plus haut dans la modelisation...
Discussions similaires