Why String.Equals is returning false? - c#

I have the following C# code (from a library I'm using) that tries to find a certificate comparing the thumbprint. Notice that in the following code both mycert.Thumbprint and certificateThumbprint are strings.
var certificateThumbprint = AppSettings.CertificateThumbprint;
var cert =
myStore.Certificates.OfType<X509Certificate2>().FirstOrDefault(
mycert =>
mycert.Thumbprint != null && mycert.Thumbprint.Equals(certificateThumbprint)
);
This fails to find the certificate with the thumbprint because mycert.Thumbprint.Equals(certificateThumbprint) is false even when the strings are equal. mycert.Thumbprint == certificateThumbprint also returns false, while mycert.Thumbprint.CompareTo(certificateThumbprint) returns 0.
I might be missing something obvious, but I can't figure out why the Equals method is failing. Ideas?

CompareTo ignores certain characters:
static void Main(string[] args)
{
var a = "asdas"+(char)847;//add a hidden character
var b = "asdas";
Console.WriteLine(a.Equals(b)); //false
Console.WriteLine(a.CompareTo(b)); //0
Console.WriteLine(a.Length); //6
Console.WriteLine(b.Length); //5
//watch window shows both a and b as "asdas"
}
(Here, the character added to a is U+034F, Combining Grapheme Joiner.)
So CompareTo's result is not a good indicator of a bug in Equals. The most likely reason of your problem is hidden characters. You can check the lengths to be sure.
See this for more info.

You may wish to try using an overload of String.Equals that accepts a parameter of type StringComparison.
For example:
myCert.Thumbprint.Equals(certificateThumbprint, StringComparison.[SomeEnumeration])
Where [SomeEnumeration] is replaced with one of the following enumerated constants:
- CurrentCulture
- CurrentCultureIgnoreCase
- InvariantCulture
- InvariantCultureIgnoreCase
- Ordinal
- OrdinalIgnoreCase
Reference the MSDN Documentation found here.

Sometimes when we insert data in database it stores some spaces like "question ". And when you will try to compare it with "question" it returns false. So my suggestion is: please check the value in database or use Trim() method.
In your case, please try:
mycert.Thumbprint != null && mycert.Thumbprint.trim().equals(certificateThumbprint.trim())
I think it will return true if any record will exist.

Related

C# Check List against part of string

I have a list which contains values such as:
readies action
uses action
begins to cast action
I want to compare a string to match against this list and return a boolean based on that. So for example:
string compare = "The Manipulator uses action";
To do this I have tried two different methods, the first being:
if (mylist.Contains(compare)) { //True }
and the second (with Linq):
if (mylist.Any(str => str.Contains(compare))) { //True }
The problem I'm having is both of these methods match against an extended string. What I mean by that is if compare == "uses action" the statement returns true, but if compare == "The Manipulator uses action" the statement returns false.
Any help on fixing this would be most appreciated! :)
I'm not totally following what you're looking for, so there are 2 different solutions, besed on expected outcome.
If you're only trying to match exactly the same string from within the list Any is the way to go, but you should use == instead of Contains:
if (mylist.Any(str => str == compare)) { //True }
If you'd like extended string to also match, you use Contains, but instead of calling str.Contains(compare) call compare.Contains(str):
if (mylist.Any(str => compare.Contains(str))) { //True }

Why this string ("ʿAbdul-Baha'"^^mso:text#de) doesn't start with "?

"\"ʿAbdul-Baha'\"^^mso:text#de".StartsWith("\"") // is false
"\"Abdul-Baha'\"^^mso:text#de".StartsWith("\"") // is true
(int)'ʿ' // is 703`
is there anyone could tell me Why?
You need to use the second parameter of the function BeginsWith; StringComparison.Ordinal (or StringComparison.OrdinalIgnoreCase). This instructs the function to compare by character value and to take no consideration to cultural information on sorting. This quote is from the MSDN-link below:
"An operation that uses word sort rules performs a culture-sensitive comparison wherein certain nonalphanumeric Unicode characters might have special weights assigned to them. Using word sort rules and the conventions of a specific culture, the hyphen ("-") might have a very small weight assigned to it so that "coop" and "co-op" appear next to each other in a sorted list."
This seems to affect how BeginsWith performs depending on locale/culture (see the comments on OP's post) - it works for some but not for others.
In my example (unit-test) below I show that if you convert the strings to a char-array and look at the first character, it it actually the same. When calling the BeginsWith-function you need to add the Ordinal comparison to get the same result.
For reference my locale is Swedish.
For further info: MSDN: StringComparison Enumeration
[Test]
public void BeginsWith_test()
{
const string string1 = "\"ʿAbdul-Baha'\"^^mso:text#de";
const string string2 = "\"Abdul-Baha'\"^^mso:text#de";
var chars1 = string1.ToCharArray();
var chars2 = string2.ToCharArray();
Assert.That(chars1[0], Is.EqualTo('"'));
Assert.That(chars2[0], Is.EqualTo('"'));
Assert.That(string1.StartsWith("\"", StringComparison.InvariantCulture), Is.False);
Assert.That(string1.StartsWith("\"", StringComparison.CurrentCulture), Is.False);
Assert.That(string1.StartsWith("\"", StringComparison.Ordinal), Is.True); // Works
Assert.That(string2.StartsWith("\""), Is.True);
}

C# weird string behaviour?

I have a string variable as below:
string testVar = "abc ";
Then I have a if statement as below:
if(this.testVar[this.testVar.Length-1].Equals(" "))
From the above I'm trying to find if the last character is space, if it is space then do something. But it is always false even if my testVar = "abc "?
testVar[…] returns a char, not a string. That’s why an Equals test with a string always returns false. You can fix this easily by comparing to a char. you also don’t need Equals:
if (testVar[testVar.Length - 1] == ' ')
It is worth nothing that, if you had used == initially instead of Equals, you would have gotten a compile time error explaining the problem. This illustrates nicely why it’s good to use early binding rather than late binding (Equals takes an object and hence doesn’t offer compile-time type checking).
Why do you not just use:
if (testVar.EndsWith (" "))
It is always false because a char is never equal to a string.
This would work:
if (this.testVar[this.testVar.Length-1].Equals(' '))
or this
if (this.testVar[this.testVar.Length-1] == ' ')
check this dude
var result = str.Substring(str.LastIndexOf(' ') + 1);

c# string Compare

I am trying to create list filter in .net MVC4 C#.
I have ajax query that sends string to controller and according to matches in database it returns number of records.
So when the String is IsNullOrEmpty() and IsNullOrWhiteSpace() it brings me fine result.
I have problem in matching values now.
Although it seemed me easy so i tried-
Controller
public ActionResult SearchAccountHead(string accountHead)
{
var students = from s in db.LedgerTables
select s;
List<LedgerModel> ledge = null;
if (!String.IsNullOrEmpty(accountHead))
{
//Returns non-empty records
}
if (String.IsNullOrEmpty(accountHead) && String.IsNullOrWhiteSpace(accountHead))
{
//Checks whether string is null or containing whitespace
//And returns filtered result
}
return PartialView(ledge);
}
Now if I have string that doesn't match with string I have been using in controller then I tried mapping it-
if (String.IsNullOrEmpty(accountHead) && String.IsNullOrWhiteSpace(accountHead) && !String.Compare(accountHead))
if (String.IsNullOrEmpty(accountHead) && String.IsNullOrWhiteSpace(accountHead) && !String.Compare(AccountHead,ledge.AccountHead))
But in both cases it didn't work.
How can I get into second method when string doesn't match?
You can't apply string.Compare with !, since string.Compare would return an integer value. If you are comparing string for equality then its better if you use string.Equals, it also has an overload which does case insensitive comparison.
You can have the check like:
if (String.IsNullOrWhiteSpace(accountHead) &&
!String.Equals(AccountHead, ledge.AccountHead,StringComparison.InvariantCultureIgnoreCase))
As a side note you can remove
if (String.IsNullOrEmpty(AccountHead) && String.IsNullOrWhiteSpace(AccountHead))
and just use
if (String.IsNullOrWhiteSpace(AccountHead))
since string.IsNullOrWhiteSpace checks for empty strings as well.
You can use string.Equals() and pass it an option for comparison logic. Something like this:
AccountHead.Equals(ledge.AccountHead, StringComparison.InvariantCultureIgnoreCase)
This will compare AccountHead and ledge.AccountHead in a case-insensitive manner using invariant culture rules. There are additional options to choose from as well.
You can use String.Compare to do the same as String.Equals, however, it's a bit less succinct e.g.
String.Compare(AccountHead, ledge.AccountHead, StringComparison.OrdinalIgnoreCase) <> 0
Here's the shorter way...
!AccountHead.Equals(ledge.AccountHead, StringComparison.OrdinalIgnoreCase);
You can keep it simple and write something like this !(accountHead == ledge.AccountHead).
You don't need comparison as i see, but to check if strings are equal or not. Usually Equals is the best way to do that, but "==" does semantic and object.ReferenceEquals -- referential comparison. So i would go with that one.
Hope this helps

Need help with error:: The best overloaded method match for 'int.Parse(string)' has some invalid arguments

dsgetQuesTypeID = objdalQuesTypeID.GetQuesTypeID(int.Parse(QuesTypeID)); //error here
Whats wrong ?
if you see the int.Parse in metadata explorer
//
// Summary:
// Converts the string representation of a number to its 32-bit signed integer
// equivalent.
//
// **Parameters:
// s:
// A string containing a number to convert.**
//
// Returns:
// A 32-bit signed integer equivalent to the number contained in s.
//
public static int Parse(string s);
it requires a string input to be parsed , but QuesTypeID is int so that's why no overloaded method is found so to correct the problem , you need to do following
int.Parse(QuesTypeID.ToString());
You have a member with the same name QuesTypeID as the name of the variable passed to the method. One is int and one is String. Try to rename the variable from the method to something else, like: quesTypeID. I think this would solve your problem. Also you should use Int.TryParse instead of Int.Parse.
You maybe passing null value into GetQuesTypeID(string QuesTypeID)

Categories