Datatypes in c# - c#

I am in need of an integer data type which starts with 00 from 1 to 10 and 0 from 10 to 99.
Is there any data type in c#
Thank you very much....

You can use pretty much any integer type for that(int, uint, etc); the important part is how you format it. In this case:
string s = i.ToString("000");
The integer data type is just the value - leading zeros don't exist or not exist - simply that isn't the job of an integer.
You could always create a custom struct of course, taking the integer value in the constuctor (and maybe a custom conversion operator), overriding the ToString() method (and probably Equals, GetHashCode, etc).
Just for kicks:
public struct TriDigit : IComparable, IComparable<TriDigit>, IComparable<int>, IEquatable<TriDigit>, IEquatable<int>
{
private readonly int value;
public TriDigit(int value)
{
if (value < 0 || value > 999) throw new ArgumentOutOfRangeException("value");
this.value = value;
}
public override string ToString()
{
return value.ToString("000");
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (obj is TriDigit) return ((TriDigit)obj).value == value;
if (obj is int) return ((int)obj) == value;
return false;
}
public int CompareTo(object obj)
{
if (obj == null) return -1;
if(obj is TriDigit) return value.CompareTo(((TriDigit)obj).value);
if (obj is int) return value.CompareTo((int)obj);
return -1;
}
public override int GetHashCode()
{
return value;
}
public static explicit operator TriDigit(int value)
{
return new TriDigit(value);
}
public static implicit operator int(TriDigit value)
{
return value.value;
}
int IComparable<TriDigit>.CompareTo(TriDigit other)
{
return value.CompareTo(other.value);
}
int IComparable<int>.CompareTo(int other)
{
return value.CompareTo(other);
}
bool IEquatable<TriDigit>.Equals(TriDigit other)
{
return value == other.value;
}
bool IEquatable<int>.Equals(int other)
{
return value == other;
}
}

Sounds like you want a format string, not a data type.
Console.WriteLine("{0:D3}", i);

You can simply use int or if it must not be negative uint (unsigned integer). There are smaller data types, but for most applications they're not worth worrying about.

If you are saying that you need an integer with a legal range from 1 to 10, with an index that starts at zero, then the answer is no. You'll need to make your own an ADT for that.

It's formatting you want, not a new datatype. Read all about it here: MSDN's page on Custom Numeric Format Strings.

You can use PadLeft(int totalWidth, char paddingChar) like..
int myNumber=12
string myStringNumber = myNumber.ToString().PadLeft(3, '0');

Related

Overriding GetHash() And Equals()

I am having trouble overriding the GetHashCode() method and the Equals() method.
public class Coordinate
{
int x;
int y;
public Coordinate(int p,int q)
{
this.x = p ;
this.y = q;
}
}
Suppose I created two Coordinate point objects with same x and y coordinates .
I want my program to understand that they are equal.
Coordinate Point 1 = new Coordinate(0,0);
Coordinate Point 2 = new Coordinate(0,0);
By default they are giving different GetHashCode() as expected.
I want them to give same hash code by overriding it and then use that hash code as a Key to generate values from a Dictionary. After searching about it, I know that I also have to override Equals().
You have to override Equals(), because if two objects have the same hashcode, it doesn't mean they are to be considered equal. The hashcode simply acts as an "index" to speed up searches.
Every time you use new, an instance is created and it will not be the same instance as another instance. This is what ReferenceEquals() checks - imagine two identical bottles of soda - they're the same, but they're not the same bottle.
Equals() is meant to check whether you (the developer) want to consider two instances as equal, even though they are not the same instance.
You can implement something in this vein:
public override bool Equal(Object o) {
if (object.ReferenceEquals(o, this))
return true;
Coordinate other = o as Coordinate;
else if (null == other)
return false;
return x == other.x && y == other.y;
}
public override int GetHashCode() {
return x.GetHashCode() ^ y.GetHashCode();
}
where Equals return true if and only if instances are equal while GetHashCode() does a quick estimation (instances are not equal if they have different hash code, the reverse, however, is not true) and ensures uniform distribution of the hashes as far as it's possible (so that in Dictionary and alike structures we have roughly equally number of values per each key)
https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx
https://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.110).aspx
I would override the named methods like this. For the GetHashCode method I took one of several options from this question, but you can choose another if you like.
I also changed the class to immutable. You should only use immutable properties/fields to calculate the hashcode.
public class Coordinate {
public Coordinate(int p, int q) {
x = p;
y = q;
}
private readonly int x;
private readonly int y;
public int X { get { return x; } }
public int Y { get { return y; } }
public override int GetHashCode() {
unchecked // Overflow is fine, just wrap
{
int hash = (int) 2166136261;
// Suitable nullity checks etc, of course :)
hash = (hash * 16777619) ^ x.GetHashCode();
hash = (hash * 16777619) ^ y.GetHashCode();
return hash;
}
}
public override bool Equals(object obj) {
if (obj == null)
return false;
var otherCoordinate = obj as Coordinate;
if (otherCoordinate == null)
return false;
return
this.X == otherCoordinate.X &&
this.Y == otherCoordinate.Y;
}
}
Here's a simple way you to do it.
First, override the ToString() method of your class to something like this:
public override string ToString()
{
return string.Format("[{0}, {1}]", this.x, this.y);
}
Now you can easily override GetHashCode() and Equals() like this:
public override int GetHashCode()
{
return this.ToString().GetHashCode();
}
public override bool Equals(object obj)
{
return obj.ToString() == this.ToString();
}
Now if you try this:
Coordinate p1 = new Coordinate(5, 0);
Coordinate p2 = new Coordinate(5, 0);
Console.WriteLine(p1.Equals(p2));
you'll get:
True
What you try to do typically happens when you have immutable objects and such, anyway if you don't want to use a struct, you can do it like this :
public class Coord : IEquatable<Coord>
{
public Coord(int x, int y)
{
this.X = x;
this.Y = y;
}
public int X { get; }
public int Y { get; }
public override int GetHashCode()
{
object.Equals("a", "b");
// Just pick numbers that are prime between them
int hash = 17;
hash = hash * 23 + this.X.GetHashCode();
hash = hash * 23 + this.Y.GetHashCode();
return hash;
}
public override bool Equals(object obj)
{
var casted = obj as Coord;
if (object.ReferenceEquals(this, casted))
{
return true;
}
return this.Equals(casted);
}
public static bool operator !=(Coord first, Coord second)
{
return !(first == second);
}
public static bool operator ==(Coord first, Coord second)
{
if (object.ReferenceEquals(second, null))
{
if (object.ReferenceEquals(first, null))
{
return true;
}
return false;
}
return first.Equals(second);
}
public bool Equals(Coord other)
{
if (object.ReferenceEquals(other, null))
{
return false;
}
return object.ReferenceEquals(this, other) || (this.X.Equals(other.X) && this.Y.Equals(other.Y));
}
}
Note . You really should make your class immutable if you do custom equality since it could break your code if you use a hash based collection.
I think it is considered good practice to do all those overloads when you want custom equality checking like you do. Especially since when object.GetHashCode() returns the same value for two object, Dictionary and other hash based collections use the default equality operator which uses object.Equals.
Object.ReferenceEquals(Ob,Ob) determine reference equality, a.k.a if both reference point to the same allocated value, two references being equal ensure you it's the exact same object.
Object.Equals(Ob) is the virtual method in object class, by default it compares references just like Object.ReferenceEquals(Ob,Ob)
Object.Equals(Ob,Ob) calls the Ob.Equals(Ob), so yeah just a static shorthand checking for null beforehand IIRC.

Error while fetching data from sorted dictionary in C#

I have a SortedDictionary<Package, List<string>>. Following is the Package class:
using System;
namespace GetPackageInfo
{
public class Package : IComparable, IEquatable<Package>
{
public string PackageName;
public string Version;
public Package()
{
}
public Package(string packageName)
{
this.PackageName = packageName;
}
public override int GetHashCode()
{
unchecked
{
int result = 17;
result = result * 23 + ((PackageName != null) ? this.PackageName.GetHashCode() : 0);
result = result * 23 + ((Version != null) ? this.Version.GetHashCode() : 0);
return result;
}
}
public bool Equals(Package other)
{
if (ReferenceEquals(null, other))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return Equals(this.PackageName, other.PackageName) &&
Equals(this.Version, other.Version);
}
public override bool Equals(object obj)
{
Package temp = obj as Package;
if (temp == null)
return false;
return this.Equals(temp);
}
public override string ToString()
{
return string.Format("PackageName: {0}, Version: {1}", PackageName, Version);
}
public int CompareTo(object obj)
{
if (obj == null)
return 1;
if (obj != null)
return (Equals(obj) ? -1 : 1);
else
throw new ArgumentException("Object is not a Temperature");
}
Whenever I do a Contains or ContainsKey on the SortedDictionary, it does not work even when the name and version is the same.
if (nugetPackagesInfo.Keys.Any(p => p.Equals(package)))
{
//List<string> currPackage;
//nugetPackagesInfo.TryGetValue(package, out currPackage);
if (!nugetPackagesInfo[package].Contains(packageFile))
{
nugetPackagesInfo[package].Add(packageFile);
}
nuGetPackagesInfo is my dictionary object. The Any returns true though. But once it is passed and gets to nugetPackagesInfo[package], then it throws the KeyNotFoundException. Can you please help me figure it out? Is my CompareTo not correct?
Your implementation of CompareTo doesn't seem to be correct. In fact, you don't implement any ordering of packages. You should, most likely, order packages by name, and if equal by version.
The core of Package.CompareTo should look like this (simplified; not taking care of other == null):
// try name ordering
int nameOrdering = this.Name.CompareTo(other.Name);
// names not equal ⇒ ordering is clear and no need to inspect further
if (nameOrdering != 0)
{
return nameOrdering;
}
// names are equal ⇒ resort to version ordering
else
{
return this.Version.CompareTo(other.Version);
}
You should also read the documentation for String.CompareTo() because of its culture-specific semantics.
Change CompareTo and GetHashCode to these implementations.
public int CompareTo(object obj)
{
if (obj == null)
return 1;
return this.ToString().CompareTo(obj.ToString());
}
public override int GetHashCode()
{
unchecked
{
return ((PackageName != null ? PackageName.GetHashCode() : 0)*397) ^ (Version != null ? Version.GetHashCode() : 0);
}
}
public override string ToString()
{
return string.Format("PackageName: {0}, Version: {1}", PackageName??"", Version ?? "");
}
CompareTo - see the documentation. By using ToString() you get a comparison on the package name and then the version without having to do your own checks. Just make sure that ToString is correct (I added null check so it does not throw an Exception).
GetHashCode - not sure where you got your implementation from. You need to make sure that the hashcode is always unique for that item unless they truely are equal. This is the implementation I found on this previous answer on SO, see the last edit in the answer..
Your CompareTo method should work as this:
return -1 if this is smaller than obj
return 1 if this is bigger than obj and
most important: return 0 if this equals obj

I'm implementing a CaseAccentInsensitiveEqualityComparer for Strings. I'm not sure how to implement the GetHashCode

My code is like this:
public class CaseAccentInsensitiveEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0;
}
public int GetHashCode(string obj)
{
// not sure what to put here
}
}
I know the role of GetHashCode in this context, what I'm missing is how to produce the InvariantCulture, IgnoreNonSpace and IgnoreCase version of obj so that I can return it's HashCode.
I could remove diacritics and the case from obj myself and then return it's hashcode, but I wonder if there's a better alternative.
Returning 0 inside GetHashCode() works (as pointed out by #Michael Perrenoud) because Dictionaries and HashMaps call Equals() just if GetHashCode() for two objects return the same values.
The rule is, GetHashCode() must return the same value if objects are equal.
The drawback is that the HashSet (or Dictionary) performance decreases to the point it becomes the same as using a List. To find an item it has to call Equals() for each comparison.
A faster approach would be converting to Accent Insensitive string and getting its hashcode.
Code to remove accent (diacritics) from this post
static string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
Comparer code:
public class CaseAccentInsensitiveEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Compare(x, y, CultureInfo.InvariantCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0;
}
public int GetHashCode(string obj)
{
return obj != null ? RemoveDiacritics(obj).ToUpperInvariant().GetHashCode() : 0;
}
private string RemoveDiacritics(string text)
{
return string.Concat(
text.Normalize(NormalizationForm.FormD)
.Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) !=
UnicodeCategory.NonSpacingMark)
).Normalize(NormalizationForm.FormC);
}
}
Ah, excuse me, I had my methods mixed up. When I implemented something like this before I just returned the hash code of the object itself return obj.GetHashCode(); so that it would always enter the Equals method.
Okay, after much confusion I believe I've got myself straight. I found that returning zero, always, will force the comparer to use the Equals method. I'm looking for the code I implemented this in to prove that and put it up here.
Here's the code to prove it.
class MyArrayComparer : EqualityComparer<object[]>
{
public override bool Equals(object[] x, object[] y)
{
if (x.Length != y.Length) { return false; }
for (int i = 0; i < x.Length; i++)
{
if (!x[i].Equals(y[i]))
{
return false;
}
}
return true;
}
public override int GetHashCode(object[] obj)
{
return 0;
}
}

C# class definition HELP

This is a project question that i just cant seem to answer
using System;
namespace ConsoleApplication2
{
internal class Equipment : IComparable
{
private readonly string type;
private readonly int serialNo;
private string colour;
public decimal cost;
public Equipment(string type, int serialNo)
{
this.type = type == null ? "" : type.Trim();
this.serialNo = serialNo;
}
public string Key
{
get { return type + ":" + serialNo; }
}
int IComparable.CompareTo(object obj)
{
return 0;
}
}
}
(a) Override the appropriate method o ensure that different instances of the class that represent the same equipment item will be considered the same in the system.
(b) Override the appropriate method to enable instances of this class to be stored (and found) by key in a hash table
You should override the Equals and GetHashCode methods for this purpose.
Override Equals() with an appropriate logic of comparision
Override GetHashCode(), see GetHashCode Guidelines in C#
You must start reading this before doing such a task
Why is it important to override GetHashCode when Equals method is overriden in C#?
Writing GetHashCode manually is not that easy. Anyhow, that's code generated for this purpose by ReSharper. It's a complete solution. (It should be contained within your class definition of course). But what would you say, if you were asked - why and how it works? It might be embarassing.
So, apart from GetHashCode and Equals, which others have suggested you reading about, you might also look up http://msdn.microsoft.com/en-us/library/system.object.referenceequals.aspx as well as http://msdn.microsoft.com/en-us/library/a569z7k8(v=VS.100).aspx
As for the mystery behind 397 in GetHashCode, have a look at this question here on StackOverflow: Why is '397' used for ReSharper GetHashCode override?
public bool Equals(Equipment other)
{
if (ReferenceEquals(null, other))
{
return false;
}
if (ReferenceEquals(this, other))
{
return true;
}
return Equals(other.colour, colour) && other.cost == cost && other.serialNo == serialNo && Equals(other.type, type);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != typeof (Equipment))
{
return false;
}
return Equals((Equipment) obj);
}
// note: if "Override the appropriate method to enable instances of this class
// to be stored (and found) by key in a hash table" is supposed to mean that only type and
// serialNo should be taken into account (since they are used to generate
// the Key value) - just remove the lines with cost and colour
public override int GetHashCode()
{
unchecked
{
int result = (colour != null ? colour.GetHashCode() : 0);
result = (result*397) ^ cost.GetHashCode();
result = (result*397) ^ serialNo;
result = (result*397) ^ (type != null ? type.GetHashCode() : 0);
return result;
}
}

Creating a generic method in C#

I am trying to combine a bunch of similar methods into a generic method. I have several methods that return the value of a querystring, or null if that querystring does not exist or is not in the correct format. This would be easy enough if all the types were natively nullable, but I have to use the nullable generic type for integers and dates.
Here's what I have now. However, it will pass back a 0 if a numeric value is invalid, and that unfortunately is a valid value in my scenarios. Can somebody help me out? Thanks!
public static T GetQueryString<T>(string key) where T : IConvertible
{
T result = default(T);
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
result = (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
What if you specified the default value to return, instead of using default(T)?
public static T GetQueryString<T>(string key, T defaultValue) {...}
It makes calling it easier too:
var intValue = GetQueryString("intParm", Int32.MinValue);
var strValue = GetQueryString("strParm", "");
var dtmValue = GetQueryString("dtmPatm", DateTime.Now); // eg use today's date if not specified
The downside being you need magic values to denote invalid/missing querystring values.
I know, I know, but...
public static bool TryGetQueryString<T>(string key, out T queryString)
What about this? Change the return type from T to Nullable<T>
public static Nullable<T> GetQueryString<T>(string key) where T : struct, IConvertible
{
T result = default(T);
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
result = (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
Convert.ChangeType() doesn't correctly handle nullable types or enumerations in .NET 2.0 BCL (I think it's fixed for BCL 4.0 though). Rather than make the outer implementation more complex, make the converter do more work for you. Here's an implementation I use:
public static class Converter
{
public static T ConvertTo<T>(object value)
{
return ConvertTo(value, default(T));
}
public static T ConvertTo<T>(object value, T defaultValue)
{
if (value == DBNull.Value)
{
return defaultValue;
}
return (T) ChangeType(value, typeof(T));
}
public static object ChangeType(object value, Type conversionType)
{
if (conversionType == null)
{
throw new ArgumentNullException("conversionType");
}
// if it's not a nullable type, just pass through the parameters to Convert.ChangeType
if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
// null input returns null output regardless of base type
if (value == null)
{
return null;
}
// it's a nullable type, and not null, which means it can be converted to its underlying type,
// so overwrite the passed-in conversion type with this underlying type
conversionType = Nullable.GetUnderlyingType(conversionType);
}
else if (conversionType.IsEnum)
{
// strings require Parse method
if (value is string)
{
return Enum.Parse(conversionType, (string) value);
}
// primitive types can be instantiated using ToObject
else if (value is int || value is uint || value is short || value is ushort ||
value is byte || value is sbyte || value is long || value is ulong)
{
return Enum.ToObject(conversionType, value);
}
else
{
throw new ArgumentException(String.Format("Value cannot be converted to {0} - current type is " +
"not supported for enum conversions.", conversionType.FullName));
}
}
return Convert.ChangeType(value, conversionType);
}
}
Then your implementation of GetQueryString<T> can be:
public static T GetQueryString<T>(string key)
{
T result = default(T);
string value = HttpContext.Current.Request.QueryString[key];
if (!String.IsNullOrEmpty(value))
{
try
{
result = Converter.ConvertTo<T>(value);
}
catch
{
//Could not convert. Pass back default value...
result = default(T);
}
}
return result;
}
You can use sort of Maybe monad (though I'd prefer Jay's answer)
public class Maybe<T>
{
private readonly T _value;
public Maybe(T value)
{
_value = value;
IsNothing = false;
}
public Maybe()
{
IsNothing = true;
}
public bool IsNothing { get; private set; }
public T Value
{
get
{
if (IsNothing)
{
throw new InvalidOperationException("Value doesn't exist");
}
return _value;
}
}
public override bool Equals(object other)
{
if (IsNothing)
{
return (other == null);
}
if (other == null)
{
return false;
}
return _value.Equals(other);
}
public override int GetHashCode()
{
if (IsNothing)
{
return 0;
}
return _value.GetHashCode();
}
public override string ToString()
{
if (IsNothing)
{
return "";
}
return _value.ToString();
}
public static implicit operator Maybe<T>(T value)
{
return new Maybe<T>(value);
}
public static explicit operator T(Maybe<T> value)
{
return value.Value;
}
}
Your method would look like:
public static Maybe<T> GetQueryString<T>(string key) where T : IConvertible
{
if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
{
string value = HttpContext.Current.Request.QueryString[key];
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
//Could not convert. Pass back default value...
return new Maybe<T>();
}
}
return new Maybe<T>();
}
I like to start with a class like this
class settings
{
public int X {get;set;}
public string Y { get; set; }
// repeat as necessary
public settings()
{
this.X = defaultForX;
this.Y = defaultForY;
// repeat ...
}
public void Parse(Uri uri)
{
// parse values from query string.
// if you need to distinguish from default vs. specified, add an appropriate property
}
This has worked well on 100's of projects. You can use one of the many other parsing solutions to parse values.

Categories