How can I override TryParse? - c#

I would like to override bool's TryParse method to accept "yes" and "no." I know the method I want to use (below) but I don't know how to override bool's method.
... bool TryParse(string value, out bool result)
{
if (value == "yes")
{
result = true;
return true;
}
else if (value == "no")
{
result = false;
return true;
}
else
{
return bool.TryParse(value, result);
}
}

You can't override a static method. You could however create an extension method.
public static bool TryParse(this string value, out bool result)
{
// For a case-insensitive compare, I recommend using
// "yes".Equals(value, StringComparison.OrdinalIgnoreCase);
if (value == "yes")
{
result = true;
return true;
}
if (value == "no")
{
result = false;
return true;
}
return bool.TryParse(value, out result);
}
Put this in a static class, and call your code like this:
string a = "yes";
bool isTrue;
bool canParse = a.TryParse(out isTrue);

TryParse is a static method. You can't override a static method.

TryParse is a static method and you can't override static methods.
You could always try to create an extension method for strings to do what you want:
public static bool ParseYesNo(this string str, out bool val)
{
if(str.ToLowerInvariant() == "yes")
{
val = true;
return true;
}
else if (str.ToLowerInvariant() == "no")
{
val = false;
return true;
}
return bool.TryParse(str, out val);
}

You cannot override TryParse. However, you could create an extension method on string for convenience.
public static class StringExtension
{
public static bool TryParseToBoolean(this string value, bool acceptYesNo, out bool result)
{
if (acceptYesNo)
{
string upper = value.ToUpper();
if (upper == "YES")
{
result = true;
return true;
}
if (upper == "NO")
{
result = false;
return true;
}
}
return bool.TryParse(value, out result);
}
}
And then it would be used like so:
public static class Program
{
public static void Main(string[] args)
{
bool result;
string value = "yes";
if (value.TryParseToBoolean(true, out result))
{
Console.WriteLine("good input");
}
else
{
Console.WriteLine("bad input");
}
}
}

This is not possible.

Related

Recursive Search Binary Search Tree with one parameter

I am trying to search through a binary search tree using a recursive method in C#.
So far I am able to successfully execute this method using two parameters:
public bool Search(int value, Node start)
{
if(start == null) {
return false;
}
else if(value == start.value) {
return true;
}
else {
if(value < start.value) {
Search(value, start.LeftChild.value);
}
else {
Search(value, start.RightChild.value);
}
}
}
However I would like to see if there's a way to use only one parameter such as using the following method signature:
public bool Search(int value){}
I also have the following that I can use to access the tree:
public class BinarySearchTree
{
private Node<int> root;
public Node<int> Root { get => root; set => root = value; }
public BinarySearchTree()
{
this.root = null;
}
}
public bool Search(int value)
{
return SearchTree(value, root);
bool SearchTree(int value, Node<int> start)
{
if(start == null)
return false;
else if(value == start.Value)
return true;
else
{
if(value < start.Value)
return SearchTree(value, start.LeftChild);
else
return SearchTree(value, start.RightChild);
}
}
}
if there's a way to use only one parameter such as using the following method signature:
sure. make it a method in Node class.
public class Node
{
public Node LeftChild, RightChild;
public int value;
public bool Search(int value)
{
if (value == this.value)
{
return true;
}
else
{
if (value < this.value)
{
return this.LeftChild?.Search(value) ?? false;
}
else
{
return this.RightChild?.Search(value) ?? false;
}
}
}
}
then for tree call it as tree.Root.Search(0);

Value of registry key is returned as null even though it has a value

i'm trying to get the value of registry key and compare it afterwards with a specific value if it matches this value. Unfortunately my method return a "null" value and i don't know why.
if (HelperRegistry.RegistryKeyValueExists("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Office\\Outlook\\Addins\\Connect to Outlook.AddinModule", "FriendlyName", "Connect to Outlook"))
{
OutputHandler.ColorCMDOutput("Do this", ConsoleColor.Green);
}
else
{
OutputHandler.ColorCMDOutput("Do that", ConsoleColor.Red);
}
static public bool RegistryKeyValueExists(string keyName, string valueName, string valueToBeTested)
{
try
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName + "\\" + valueName))
if (key != null)
{
Object o = key.GetValue("FriendlyName");
if (o != null)
{
string test = Convert.ToString(o);
if (test == valueToBeTested)
{
return true;
}
}
}
return false;
}
catch
{
return false;
}
}
I went with a different approach. I'm using a different mehtod (i already got) to check if the valueName(valueData) exists at all and then compare it with the valueData that i want to be tested.
static public bool RegistryKeyValueDataIdentical(string keyName, string valueName, string valueData)
{
bool returnvalue = false;
try
{
if (RegistryPathExists(keyName,valueName))
{
if (valueData == Microsoft.Win32.Registry.GetValue(keyName, valueName, null).ToString())
returnvalue = true;
else returnvalue = false;
}
else returnvalue = false;
}
catch
{
returnvalue = false;
}
return returnvalue;
}
static public bool RegistryPathExists(string keyName, string valueName)
{
try
{
return (Microsoft.Win32.Registry.GetValue(keyName, valueName, null) != null);
}
catch
{
return false;
}
}

C#: Test if an object implements any of a list of interfaces?

I want to test if a type implements one of a set of interfaces.
ViewData["IsInTheSet"] =
model.ImplementsAny<IInterface1, IInterface2, IInterface3, IInterface4>();
I have written the following extension methods to handle this.
Is there a more extensible way to write the following code? I would prefer not to have to write a new method while still leveraging generics.
public static bool Implements<T>(this object obj)
{
Check.Argument.IsNotNull(obj, "obj");
return (obj is T);
}
public static bool ImplementsAny<T>(this object obj)
{
return obj.Implements<T>();
}
public static bool ImplementsAny<T,V>(this object obj)
{
if (Implements<T>(obj))
return true;
if (Implements<V>(obj))
return true;
return false;
}
public static bool ImplementsAny<T,V,W>(this object obj)
{
if (Implements<T>(obj))
return true;
if (Implements<V>(obj))
return true;
if (Implements<W>(obj))
return true;
return false;
}
public static bool ImplementsAny<T, V, W, X>(this object obj)
{
if (Implements<T>(obj))
return true;
if (Implements<V>(obj))
return true;
if (Implements<W>(obj))
return true;
if (Implements<X>(obj))
return true;
return false;
}
Why not use something like the following:
public static bool ImplementsAny(this object obj, params Type[] types)
{
foreach(var type in types)
{
if(type.IsAssignableFrom(obj.GetType())
return true;
}
return false;
}
Then you can call it like:
model.ImplementsAny(typeof(IInterface1),
typeof(IInterface2),
typeof(IInterface3),
typeof(IInterface4));
The way I check if an interface has been implemented is:
public static bool IsImplementationOf(this Type checkMe, Type forMe)
{
if (forMe.IsGenericTypeDefinition)
return checkMe.GetInterfaces().Select(i =>
{
if (i.IsGenericType)
return i.GetGenericTypeDefinition();
return i;
}).Any(i => i == forMe);
return forMe.IsAssignableFrom(checkMe);
}
This could be easily extended to:
public static bool IsImplementationOf(this Type checkMe, params Type[] forUs)
{
return forUs.Any(forMe =>
{
if (forMe.IsGenericTypeDefinition)
return checkMe.GetInterfaces().Select(i =>
{
if (i.IsGenericType)
return i.GetGenericTypeDefinition();
return i;
}).Any(i => i == forMe);
return forMe.IsAssignableFrom(checkMe);
});
}
Or better yet:
public static bool IsImplementationOf(this Type checkMe, params Type[] forUs)
{
return forUs.Any(forMe => checkMe.IsImplementationOf(forMe));
}
Warning: Untested
Then just do a typeof on your type parameters before passing them to this.

c# similarity help

Anyone can explain these codes for me?
public class SimilarityImages : IComparer<SimilarityImages>, IComparable
{
private readonly ComparableImage source;
private readonly ComparableImage destination;
private readonly double similarity;
public SimilarityImages(ComparableImage source, ComparableImage destination, double similarity)
{
this.source = source;
this.destination = destination;
this.similarity = similarity;
}
public ComparableImage Source
{
get
{
return source;
}
}
public ComparableImage Destination
{
get
{
return destination;
}
}
public double Similarity
{
get
{
return Math.Round(similarity * 100, 1);
}
}
public static int operator !=(SimilarityImages value, SimilarityImages compare)
{
return value.CompareTo(compare);
}
public static int operator <(SimilarityImages value, SimilarityImages compare)
{
return value.CompareTo(compare);
}
public static int operator ==(SimilarityImages value, SimilarityImages compare)
{
return value.CompareTo(compare);
}
public static int operator >(SimilarityImages value, SimilarityImages compare)
{
return value.CompareTo(compare);
}
public override string ToString()
{
return string.Format("{0}, {1} --> {2}", source.File.Name, destination.File.Name, similarity);
}
#region IComparer<SimilarityImages> Members
public int Compare(SimilarityImages x, SimilarityImages y)
{
return x.similarity.CompareTo(y.similarity);
}
#endregion
#region IComparable Members
public int CompareTo(object obj)
{
SimilarityImages other = (SimilarityImages)obj;
return this.Compare(this, other);
}
#endregion
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var other = (SimilarityImages)obj;
var equals = Source.File.FullName.Equals(other.Source.File.FullName, StringComparison.InvariantCultureIgnoreCase);
if (!equals)
{
return false;
}
equals = Destination.File.FullName.Equals(other.Destination.File.FullName, StringComparison.InvariantCultureIgnoreCase);
if (!equals)
{
return false;
}
return true;
}
public override int GetHashCode()
{
return string.Format("{0};{1}", Source.File.FullName, Destination.File.FullName).GetHashCode();
}
}
It looks kind of like String.Compare()
(Comparison of strings by value.)
however the return of integers for the operators <, >, <=, >=, ==, != is a bad practice - user expect a boolean return value.
Also, if the "images" are what I think they are (images as in a matrix of pixels), then returning a value for comparison is not intuitive - What comparison algorithm are you using? - Why are you providing only one comparison algorithm and hiding its name? - What if the images are not of same size or pixel format?

Problem with IDictionary<Complex Key, Complex Value>.Remove() implementation

Hi I don't understand why this code doesn't work - it don't remove key; I still get "2" on output.
Bencode.BencodeDict d = new myTorrent.Bencode.BencodeDict();
d.Dict.Add(new Bencode.BencodeString("info"), new Bencode.BencodeString("1"));
d.Dict.Add(new Bencode.BencodeString("info2"), new Bencode.BencodeString("2"));
d.Dict.Add(new Bencode.BencodeString("info3"), new Bencode.BencodeString("3"));
d.Remove(new Bencode.BencodeString("info2"));
Bencode.BencodeVariable s1;
s1 = d[new Bencode.BencodeString("info2")];
if (s1 != null)
Console.WriteLine(System.Text.UTF8Encoding.UTF8.GetString(s1.Encode()));
My BencodeDict and BencodeString
namespace myTorrent.Bencode
{
class BencodeDict : BencodeVariable, IDictionary<BencodeString, BencodeVariable>
{
private Dictionary<BencodeString, BencodeVariable> dict;
public BencodeDict() {
this.dict = new Dictionary<BencodeString,BencodeVariable>();
}
protected override void InternalDecode(BinaryReader data) { /*...*/ }
public override long ByteLength() { /*...*/ }
public override byte[] Encode() { /*...*/ }
//#region Overridden Methods
public override bool Equals(object ob)
{
if (ob == null)
return false;
BencodeDict y = ob as BencodeDict;
if (this.dict.Count != y.dict.Count)
return false;
BencodeVariable val;
foreach (KeyValuePair<BencodeString, BencodeVariable> keypair in this.dict)
{
if (!y.TryGetValue(keypair.Key, out val))
return false;
if (!keypair.Value.Equals(val))
return false;
}
return true;
}
public override int GetHashCode()
{
int result = 0;
foreach (KeyValuePair<BencodeString, BencodeVariable> keypair in this.dict)
{
result ^= keypair.Key.GetHashCode();
result ^= keypair.Value.GetHashCode();
}
return result;
}
#region IDictionary and IList methods
public void Add(BencodeString key, BencodeVariable value)
{
this.dict.Add(key, value);
}
public void Add(KeyValuePair<BencodeString, BencodeVariable> item)
{
this.dict.Add(item.Key, item.Value);
}
public void Clear()
{
this.dict.Clear();
}
public bool Contains(KeyValuePair<BencodeString, BencodeVariable> item)
{
if (!this.dict.ContainsKey(item.Key))
return false;
return this.dict[item.Key].Equals(item.Value);
}
public bool ContainsKey(BencodeString key)
{
foreach(KeyValuePair<BencodeString, BencodeVariable> pair in this.dict) {
if (pair.Key.Equals(key))
return true;
}
return false;
}
public void CopyTo(KeyValuePair<BencodeString, BencodeVariable>[] array, int arrayIndex) { /*...*/ }
public int Count
{
get { return this.dict.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(BencodeString key)
{
return this.dict.Remove(key);
}
public bool Remove(KeyValuePair<BencodeString, BencodeVariable> item)
{
return this.dict.Remove(item.Key);
}
public bool TryGetValue(BencodeString key, out BencodeVariable value)
{
foreach(KeyValuePair<BencodeString, BencodeVariable> pair in this.dict)
if ( pair.Key.Equals(key) ) {
value = pair.Value;
return true;
}
value = null;
return false;
}
public BencodeVariable this[BencodeString key]
{
get {
foreach(KeyValuePair<BencodeString, BencodeVariable> pair in this.dict)
if ( pair.Key.Equals(key) )
return pair.Value;
return null;
}
set { this.dict[key] = value; }
}
public ICollection<BencodeString> Keys
{
get { return this.dict.Keys; }
}
public ICollection<BencodeVariable> Values
{
get { return this.dict.Values; }
}
public IEnumerator<KeyValuePair<BencodeString, BencodeVariable>> GetEnumerator()
{
return this.dict.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.dict.GetEnumerator();
}
#endregion
}
}
class BencodeString : BencodeVariable
{
private byte[] str;
public BencodeString() {
this.str = null;
}
public BencodeString(string str) {
this.str = encoding.GetBytes(str);
}
public override bool Equals(object ob)
{
if (ob == null)
return false;
BencodeString y = ob as BencodeString;
return (encoding.GetString(this.str) == encoding.GetString(y.str));
}
public override int GetHashCode()
{
return this.str.GetHashCode();
}
}
You're relying on byte[].GetHashCode() doing something desirable. It won't. Arrays don't implement equality or hash operations - you'll get the default (identity) behaviour.
Rewrite your GetHashCode method as something like this:
public override int GetHashCode()
{
int result = 17;
foreach (byte b in str)
{
result = result * 31 + b;
}
return result;
}
(Also it's not clear what encoding is, but that's a different matter.)
Note that your Equals override will also throw a NullReferenceException if ob is a non-null reference, but not to a BencodeString.
EDIT: Assuming you're actually wanting to check for the byte arrays being the same, I wouldn't call Encoding.GetString in your equality check. There's no point. Just check the byte array contents directly. Something like this is a reasonable byte array equality check - although I'd generally prefer to write a generic equivalent:
private static bool ArraysEqual(byte[] x, byte[] y)
{
if (x == y)
{
return true;
}
if (x == null || y == null)
{
return false;
}
if (x.Length != y.Length)
{
return false;
}
for (int i = 0; i < x.Length; i++)
{
if (x[i] != y[i])
{
return false;
}
}
return true;
}
If you do want to check whether two byte arrays are decoded to equal strings, then you should use Encoding.GetString in both places... but that would rarely be an appropriate thing to do, IMO.
Mind you, it's not clear why you've got your own string-like class to start with. There are all kinds of potential problems here... unequal encodings, null references etc.
It is very important that values that are Equal also produce the same hash code. An obvious (but not necessarily efficient) workaround is this:
public override int GetHashCode()
{
return encoding.GetString(this.str).GetHashCode();
}
Making strings not behave as Unicode strings internally is a a code smell but possibly intentional here. It is normally applied at the outer interface. Your implementation would allow for the encoding to change after the string is read. But a really serious problem with that is that the dictionary is no longer valid when that happens. You won't be able to find keys back.

Categories

Resources