0

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
  • The .NET Framework provide all kind of tools for comparing case-insensitive strings. What's the problem with them? Commented May 31, 2009 at 21:17
  • The problem with them is that you have to remember to use the case-insensitive comparison every time you reference the string. It would be better to have 'case-insensitive' as an intrinsic trait of the property/type itself so that the default comparison works correctly. Commented Aug 2, 2017 at 19:24

5 Answers 5

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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

You can't have case-insensitive properties—you can only have case-insensitive operations, like a comparison. If someone accesses XHtmlOneDTDElementAttibute.Name, they will get back a string with whatever case it was created with.

Whenever you use .Name, you can implement that method in a way that ignores the case of the string.

4 Comments

So to implement this, in my XHtmlOneDTDElement - would I be able to overide the string compare function or something?
Yes. You can override the Object.Equals method, as well as implementing IComparable and overriding CompareTo.
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.
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.
1

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

Comments

1

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

Comments

1

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

3 Comments

Shall I also put a XHtmlOneDTDElementCollection between the XHtmlOneDTDElement & XHtmlOneDTDElementAttibute
typo : Shall I also put a XHtmlOneDTDAttibuteCollection between the XHtmlOneDTDElement & XHtmlOneDTDElementAttibute
Yes. You can make a KeyedCollection; see my newest answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.