I know I need a class library tp put the code into. But what type of
project do I create? And what class do I need to inherit? Seems that
string is not a choice according to intellisense.
Any help would be appreciated.
You may or may not need a different project. It might be sufficient to
simply create a new class in your current project, depending on whether
you anticipate reusing this in other projects. If you do create another
project, you'll want to create a C# DLL/class library project (I forget
what the exact terminology in the IDE is, but it something like that).
As far as inheriting goes, you shouldn't need to inherit any class. You
can't inherit System.String, because that class is sealed. If you still
want String-instance semantics, you can write an extension method for
String. For example:
static class MyExtensions
{
public static bool Contains(this string strSearch, string strFind,
StringComparison sc)
{
if (strFind.Length == 0)
{
return true;
}
for (int ich = 0; ich < strSearch.Length - strFind.Length;
ich++)
{
if (strSearch.Substring(ich,
strFind.Length).Equals(strFind, sc))
{
return true;
}
}
return false;
}
}
Then you can use it like this:
string strT = "My dog has fleas";
Console.WriteLine("My string has 'FLEAS': {0}",
strT.Contains("FLEAS", StringComparison.CurrentCultureIgnoreCase));
Any variation on that theme would do also.
Pete
Is there a reason why you use a for-loop with a Substring(), instead of
the String.IndexOf(String, StringComparison) method?
Hans Kesting
> [...]
>> Any variation on that theme would do also.
>>
>> Pete
>
> Is there a reason why you use a for-loop with a Substring(), instead of
> the String.IndexOf(String, StringComparison) method?
As I wrote: "Any variation on that theme would do also"
Thanks. Most informative part of this reply was your reference to
"extension methods". I was not aware of them. Cool. Gonna make sure I
remember that little trick.
Next thing was making me aware of another item I was unaware of, the
StringComparison enumeration.
Th documentation on the StringComparsion enumeration mentions it is
used by the String.Compare and String.Equals methods. It didn't
mention the String.IndexOf method as another responder mentions but
sure enough, the documentation shows that method does have overload(s)
that does.
This is a rhetorical question, but it seems strange that at least
three String class methods supports an overload that makes use of the
StringComparison enumeration, I wonder how come there isn't an
overload of the Contains method that also does???
Well, as you have shown, at least we can write our own.
I tried to implement this but I get a build error, says it can't find
the type System.Runtime.CompilerServices.ExtensionAttribute. Says I am
missing a reference to System.Core.dll. But when I try to add a
reference, System.Core is grayed out.
???
You are not using the 3.5 framework, which you need for the extension
methods to work (although there are tricks to work around that).
So switch your project to the 3.5 framework (see the properties) and it
will work.
Hans Kesting
>>> static class MyExtensions
>>> {
>>> public static bool Contains(this string strSearch, string strFind,
>>> StringComparison sc)
>>> {
>>> if (strFind.Length == 0)
>>> {
>>> return true;
>>> }
>>>
>>> for (int ich = 0; ich < strSearch.Length - strFind.Length; ich++)
>>> {
>>> if (strSearch.Substring(ich, strFind.Length).Equals(strFind, sc))
>>> {
>>> return true;
>>> }
>>> }
>>>
>>> return false;
>>> }
>>> }
>>>
>>> Then you can use it like this:
>>>
>>> string strT = "My dog has fleas";
>>>
>>> Console.WriteLine("My string has 'FLEAS': {0}",
>>> strT.Contains("FLEAS", StringComparison.CurrentCultureIgnoreCase));
>>>
>>> Any variation on that theme would do also.
>>
>> I tried to implement this but I get a build error, says it can't find
>> the type System.Runtime.CompilerServices.ExtensionAttribute. Says I am
>> missing a reference to System.Core.dll. But when I try to add a
>> reference, System.Core is grayed out.
>>
>> ???
>
> You are not using the 3.5 framework, which you need for the extension
> methods to work (although there are tricks to work around that).
> So switch your project to the 3.5 framework (see the properties) and it
> will work.
>
> Hans Kesting
>
>
Here is the work around:
//override the .net 3.5 compiler services for .net 2.0 compatibility
//see: http://kohari.org/2008/04/04/extension-methods-in-net-20/
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false,
Inherited = false)]
public class ExtensionAttribute : Attribute
{
}
}
Now you can use extensions with framwork 2.0
/FStampe
Why not keep it (overly) simple?
public bool fnStringContains(string strFirstString, string strSecondString)
{
bool blResults = false;
blResults = strFirstString.ToLower().Contains(strSecondString.ToLower());
return blResults;
}
Karl
Would have been nice if the help text, namely "How to: Implement and
Call a Custom Extension Method (C# Programming Guide)" had mentioned
that the topic applied only to .NER Frameword 3.5.
Anyhoo, that was it. I was working with a project I had converted from
VS2005 anf forgot to upgrade the framework version.
Anyhoo, that was it. I was working with a project I had converted from
VS2005 anf forgot to upgrade the framework version.
=====================
check out my last posting from around 8 hours before yours... There i have
given you the way to implement it into framework 2.0. Just did it myself and
it works like a charm..
/FStampe
> [...]
> This is a rhetorical question, but it seems strange that at least
> three String class methods supports an overload that makes use of the
> StringComparison enumeration, I wonder how come there isn't an
> overload of the Contains method that also does???
Yes, it seems like an odd omission. But, sometimes that sort of thing
happens. :)
> Would have been nice if the help text, namely "How to: Implement and
> Call a Custom Extension Method (C# Programming Guide)" had mentioned
> that the topic applied only to .NER Frameword 3.5.
It does, sort of. You need to look at what section of MSDN you're
reading. A topic may or may not include the "There are other versions of
this in..." box on the web site, but if it doesn't, the first thing to
realize is that that means it's only in the most recent .NET, and the
second thing to realize is that you can look at the navigation tree or the
"bread crumbs" along the top to see what version of the docs you're
looking at.
Pete
> Why not keep it (overly) simple?
>
> public bool fnStringContains(string strFirstString, string
> strSecondString)
> {
> bool blResults = false;
> blResults =
> strFirstString.ToLower().Contains(strSecondString.ToLower());
> return blResults;
> }
Because that won't produce correct results in all locales. It's probably
fine for English, and some other languages. But there are other languages
where it's not (the classic example being Turkish).
Pete
I personally would go with Karl solution.
ToLower() will use CurrentCulture as default. If the OP ever need to use
diffent culture, ToLower method have an overload for that. Wrap that
into extension method...
internal class MyExtension
{
public string bool Contains(this string source, string value)
{
return source.ToLower().Contains(value.ToLower());
}
public string bool Contains(this string source, string value,
CultureInfo culture)
{
return source.ToLower(culture).Contains(value.ToLower(culture));
}
}
Regards.
Arghh... damn!
The first method does not works as it has the same signature with
String.Contains(string value) method. Either change the name to
ContainsEx or something like that, or just use the second method and
pass the CultureInfo.CurrentCulture as the parameter.
Regards.
> I personally would go with Karl solution.
And you would run into the same bug that Karl would, should he ever
actually use it.
> ToLower() will use CurrentCulture as default. If the OP ever need to use
> diffent culture, ToLower method have an overload for that. Wrap that
> into extension method...
It's not a question of choosing the culture. It's the fact that no matter
what the culture, simply changing the case of the string and comparing
will not necessarily produce the same results as doing an actual "case
insensitive" comparison for that culture.
Pete
Hi Pete,
I'm not literally sure what do you mean by the above statement.
Would you give one test case / example that my method will fail (and
yours succeed)?
It will depend on why one is doing the comparison as to whether the
difference would be considered a "failure". But, if you're interested in
further reading, here are a couple of pages that should get you headed in
the right direction:
http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html
http://www.i18nguy.com/unicode/turkish-i18n.html
Previous threads in this newsgroup discussing the topic:
http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/a2d404b1d7da17be/
http://groups.google.com/group/microsoft.public.dotnet.framework.aspnet/browse_thread/thread/23b40b19185821d9/
Pete
I did mention that it's overly simple :)
Thanks, Pete - I did not know that.
Of course, I work for a government agency in the US, and we don't do too
many Turkish language comparisons, so it works here.
I will read the links you provided for kndg though.
I'm keen to learn, after all.
Karl
Thanks for the great links.
Yes, you are correct. My method fails if pass with Turkish characters.
For example:
"Hİ all".Contains("HI", CultureInfo.CurrentCulture) returns true where
it should return false.
After reading through your link and MSDN documentation about character
casing, now it becomes clear to me. For those who are interested to
know, this is what actually happens:
(I found that Unicode documentation also helps.
http://www.unicode.org/versions/Unicode5.0.0/ch05.pdf#G21180)
"Hİ all".ToLower() is converted to "hi all". (Actually if follow unicode
documentation it becomes h+i+[U0307]+ +a+l+l)
"HI".ToLower() will become "hi".
Since "hi" is contained in "hi all", so the output returns true (which
is incorrect).
Pete's method use String.Equal with StringComparison option for
comparison. Under the hood, it use native API which takes care of the
above headache.
Lesson learned: Do not use ToLower() or ToUpper() for string comparison.
Regards.