views:

909

answers:

5

Considering the class below
- can I do anything to implement a case-insensitive string?

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

I have edited the class to be a bit more objective and specific

+2  A: 
Dave Bauman
So to implement this, in my XHtmlOneDTDElement - would I be able to overide the string compare function or something?
divinci
Yes. You can override the Object.Equals method, as well as implementing IComparable and overriding CompareTo.
Dave Bauman
divinvi: Yes, provide a custom string comparer that compares the uppercase variants of two strings. That'll be pretty much a case insensitive comparison. You can still get into trouble if you're not careful enough and the input can contain non-English text as some languages have weird uppercase/lowercase rules.
DrJokepu
Comparing uppercase variants can have troubles as you mention, but it also has a performance hit since strings are immutable. Better off using the built-in string comparison methods, and CurrentCultureIgnoreCase or similar options.
Dave Bauman
+1  A: 

It depends what you're trying to do with the strings.

If you want to compare strings regardless of case, call String.Equals with StringComparison.OrdinalIgnoreCase. If you want to put them in a dictionary, make the dictionary's comparer StringComparer.OrdinalIgnoreCase.

Therefore, you could make a function as follows:

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

If you want a more specific solution, please tell me what you're doing with the Name property

SLaks
+1  A: 

Well, my take on this, after glancing at the spec, is that there's nothing you need to do to make the string properties case-insensitive. The concept doesn't really make sense, anyway: strings aren't case-sensitive or -insensitive; operations on them (like search and sort) are.

(I know the W3C's HTML recommendations say essentially that. It's badly-phrased.)

Michael Petrotta
A: 

Alternatively, you might want to make the property always uppercase, like this.

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; }
}
SLaks
divinci
divinci
Yes.You can make a KeyedCollection; see my newest answer
SLaks
+2  A: 

In answer to the restructured question, you could do it like this:

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.
    }
}

If you use this, you should either make Attribute.Name read-only or call ChangeKeyForItem whenever it's changed.

SLaks
great work good solution SLaks, and also I have never seen the KeyedCollection :) love SO!
divinci