2009-05-31 9 views
0

Considérant la classe ci-dessous
- Puis-je faire quelque chose pour implémenter une chaîne insensible à la casse?
Chaîne insensible à la casse C#

public class Attibute 
{ 
    // The Name should be case-insensitive 
    public string Name 
    { 
     get; 
     set; 
    } 

    public Attibute() 
    { 
    } 
} 

public class ClassWithAttributes 
{ 
    private List<Attributes> _attributes; 

    public ClassWithAttributes(){} 

    public AddAttribute(Attribute attribute) 
    { 
     // Whats the best way to implement the check? 
     _attributes.add(attribute); 
    } 
} 

Structure of an HTML 4 Document

J'ai édité la classe pour être un peu plus objectif et spécifique

+0

Le .NET Framework fournit tous les types d'outils permettant de comparer des chaînes insensibles à la casse. Quel est le problème avec eux? – KovBal

+0

Le problème avec eux est que vous devez vous rappeler d'utiliser la comparaison insensible à la casse chaque fois que vous faites référence à la chaîne. Il serait préférable d'avoir "insensible à la casse" comme un trait intrinsèque de la propriété/type lui-même afin que la comparaison par défaut fonctionne correctement. – Timbo

Répondre

2

En réponse à la question restructuré, vous pourriez le faire comme ceci:

public class Attribute { public string Name { get; set; } } 

public class AttributeCollection : KeyedCollection<string, Attribute> { 
    public AttributeCollection() : base(StringComparer.OrdinalIgnoreCase) { } 
    protected override string GetKeyForItem(Attribute item) { return item.Name; } 
} 

public class ClassWithAttributes { 
    private AttributeCollection _attributes; 

    public void AddAttribute(Attribute attribute) { 
     _attributes.Add(attribute);  
     //KeyedCollection will throw an exception 
     //if there is already an attribute with 
     //the same (case insensitive) name. 
    } 
} 

Si vous utilisez cette option, vous devez soit faire en lecture seule Attribute.Name ou appelez ChangeKeyForItem chaque fois qu'il a changé.

+0

excellent travail bonne solution SLaks, et aussi je n'ai jamais vu le KeyedCollection :) amour SO! – divinci

2

Vous ne pouvez pas avoir des propriétés sensibles à la casse — vous ne pouvez avoir des opérations insensibles à la casse, comme une comparaison. Si quelqu'un accède à XHtmlOneDTDElementAttibute.Name, il récupérera une chaîne avec le cas où il a été créé.

Chaque fois que vous utilisez .Name, vous pouvez implémenter cette méthode d'une manière qui ignore la casse de la chaîne.

+0

Donc, pour mettre en œuvre cela, dans mon XHtmlOneDTDElement - serais-je capable de dépasser la fonction de comparaison de chaînes ou quelque chose? – divinci

+0

Oui. Vous pouvez remplacer la méthode Object.Equals, ainsi que l'implémentation de CompareTo avec IComparable et overrid. –

+1

divinvi: Oui, fournissons un comparateur de chaînes personnalisé qui compare les variantes majuscules de deux chaînes. Ce sera à peu près une comparaison insensible à la casse. Vous pouvez toujours avoir des ennuis si vous n'êtes pas assez prudent et l'entrée peut contenir du texte non-anglais car certaines langues ont des règles majuscules/minuscules étranges. –

1

Cela dépend de ce que vous essayez de faire avec les chaînes.

Si vous souhaitez comparer des chaînes quel que soit le cas, appelez String.Equals avec StringComparison.OrdinalIgnoreCase. Si vous voulez les mettre dans un dictionnaire, faites le dictionnaire du dictionnaire StringComparer.OrdinalIgnoreCase.

Par conséquent, vous pourriez faire une fonction comme suit:

public class XHtmlOneDTDElementAttibute : ElementRegion { 
    public bool IsTag(string tag) { 
     return Name.Equals(tag, StringComparison.OrdinalIgnoreCase); 
    } 

    // The Name should be case-insensitive 
    public string Name { get; set; } 

    // The Value should be case-sensitive 
    public string Value { get; set; } 
} 

Si vous voulez une solution plus spécifique, s'il vous plaît me dire ce que vous faites avec la Name propriété

1

Eh bien, mon avis sur ceci, après avoir jeté un coup d'oeil à la spécification, est qu'il n'y a rien que vous devez faire pour rendre les propriétés de la chaîne insensibles à la casse. Le concept n'a pas vraiment de sens, de toute façon: les chaînes ne sont pas sensibles à la casse ou insensibles; opérations sur eux (comme la recherche et le tri) sont.

(je sais les recommandations HTML du W3C disent essentiellement que. Il est mal formulée.)

1

Alternativement, vous pouvez rendre la propriété toujours en majuscules, comme celui-ci.

public class XHtmlOneDTDElementAttibute : ElementRegion { 
    string name; 

    // The Name should be case-insensitive 
    public string Name { 
     get { return name; } 
     set { name = value.ToUpperInvariant(); } 
    } 

    // The Value should be case-sensitive 
    public string Value { get; set; } 
} 
+0

dirais-je aussi un XHtmlOneDTDElementCollection entre les XHtmlOneDTDElement & XHtmlOneDTDElementAttibute – divinci

+0

faute de frappe: dirais-je aussi un XHtmlOneDTDAttibuteCollection entre le XHtmlOneDTDElement et XHtmlOneDTDElementAttibute – divinci

+0

Oui. Vous pouvez créer une KeyedCollection; voir ma nouvelle réponse – SLaks

Questions connexes