c# syntactic sugar overloading - c#

I have the following method:
virtual public int nonNeg(int? numIn)
{
if ((numIn < 0) || (numIn ==null))
{
return 0;
}
else return (int)numIn;
}
I want to be able to have a single method which could take in either bytes, shorts, or ints to force these values to a nonnegative number. How could I accomplish this?

I would not normally suggest this, but off the top of my head the following overloads should cover most your cases. They will cover the nullable types and the non-nullable types, the compiler will select the appropriate overload.
public static T nonNeg<T>(T n) where T : struct, IComparable
{
if (n.CompareTo(default(T)) <= 0)
{
return default(T);
}
return n;
}
public static T nonNeg<T>(T? n) where T : struct, IComparable
{
if (!n.HasValue || n.Value.CompareTo(default(T)) <= 0)
{
return default(T);
}
return n.Value;
}

Or just use Math.Max( 0, numIn)

Possibly something like this (tested):
virtual public T nonNeg<T>(T numIn) where T : IComparable<T>
{
if (numIn==null){
return default(T);
}
if (Comparer<T>.Default.Compare(numIn,default(T))<0)
{
return default(T);
}
else
return (T)numIn;
}

I think you can do this with:
int negativeNumber = -22;
int nonNegativeNumber = Math.Abs(negativeNumber);
result will be 22
OR
decimal negativeNumber = -22.2;
decimal nonNegativeNumber = Math.Abs(negativeNumber);
result will be 22.2

Related

How to quicksort pairs of numbers(int and double)

I created the pair class and array class, but I'm lost on how to implement the quicksort algorithm.
I want to do it if ints are same then I should sort by double. I was able to implement quicksort with one value per index of array, but with this I just can't find any resources.
Maybe you guys have some resources or maybe you had the same problem?
By the way I'm trying to implement it with c#.
This is my pair class:
class Pair
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
And my data array class
class MyDataArray : DataArray
{
Pair[] data;
int operations = 0;
public MyDataArray(int n, int seed)
{
data = new Pair[n];
Random rand = new Random(seed);
for (int i = 0; i < n; i++)
{
data[i] = new Pair(rand.Next(1,100), rand.NextDouble());
}
}
public override int integer(int index)
{
return data[index].integer;
}
public override double doubl(int index)
{
return data[index].doubl;
}
public override void Swap(int i, int j)
{
Pair temp = data[i]; // c3 1
data[i] = data[j]; // c3 1
data[j] = temp; // c3 1
}
Your Pair class could implement IComparable<T>, and your quick sort algorithm could be implemented using the CompareTo method.
The IComparable<T> interface:
Defines a generalized comparison method that a value type or class implements to create a type-specific comparison method for ordering or sorting its instances.
You can see the documentation on the CompareTo method to see what the return values mean.
public class Pair : IComparable<Pair>
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int CompareTo(Pair other)
{
if (other == null)
{
return 1;
}
int result = integer.CompareTo(other.integer);
if (result == 0)
{
result = doubl.CompareTo(other.doubl);
}
return result;
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
If you prefer to use the comparison operators, you can implement them in terms of the CompareTo method. The documentation I liked has examples on how to do that.
//sort for integer
var SortedIntegerList = data.OrderBy(x=>x.integer);
//sort for double
var SortedDoubleList = data.OrderBy(x=>x.doubl);
OrderBy for objects uses Quicksort - What Sorting Algorithm Is Used By LINQ "OrderBy"? - so you can use that.
To avoid creating IComparer<Pair> interface you can construct it using Comparer<T>.Create from just comparison delegate:
var sorted = source.OrderBy(x => x, Comparer<Pair>.Create(
(p1, p2) => p1.Integer() - p2.Integer() != 0 ?
p1.Integer() - p2.Integer() :
Math.Sign(p1.Doubl() - p2.Doubl()))).ToList();

Sort List with duplicate keys by custom comparer

I have the List inputColl of type MyValue with many duplicate keys:
myValue1.Id=100;
myValue2.Id=100;
...etc
And I have custom comparer to compare two MyValue elements by Id:
inputColl.Sort(myValueComparer);
What am I doing wrong?
Comparer:
public class MyValueComparerById : IComparer<MyValue>
{
public int Compare(MyValue x, MyValue y)
{
if (x.Id == y.Id)
return 0;
else if (x.Id > y.Id)
return -1;
else if (x.Id < y.Id)
return 1;
return 0;
}
}
Unless your equality comparer is not implemented badly, your solution should work.
But I suggest an easier approach, using linq:
inputCol = inputCol.OrderBy(o => o.Id).ToList();
You already have an int comparer so is better to use it instead of rewriting same logic:
public class MyValueComparerById : IComparer<MyValue>
{
public int Compare(MyValue x, MyValue y)
{
return x.Id.CompareTo(y.Id);
}
}
** Update edit **
For further improvements maybe you might want to consider additional comparison in case of Id equality:
public class MyValueComparerById : IComparer<MyValue>
{
public int Compare(MyValue x, MyValue y)
{
var firstResult = x.Id.CompareTo(y.Id);
if (firstResult == 0)
{
// I'm assuming that MyValue has an additional string property named 'SomeName'
return x.SomeName.CompareTo(y.SomeName);
}
return firstResult;
}
}

Min and Max operations on enum values

Using C#, how can I take the min or max of two enum values?
For example, if I have
enum Permissions
{
None,
Read,
Write,
Full
}
is there a method that lets me do Helper.Max(Permissions.Read, Permissions.Full) and get Permissions.Full, for example?
Enums implement IComparable so you can use:
public static T Min<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) <= 0 ? a : b;
}
Since enums are convertible to integer types, you can just do:
var permissions1 = Permissions.None;
var permissions2 = Permissions.Full;
var maxPermission = (Permissions) Math.Max((int) permissions1, (int) permissions2);
Note that this could cause issues if your enum is based on an unsigned type, or a type longer than 32 bits (i.e., long or ulong), but in that case you can just change the type you are casting the enums as to match the type declared in your enum.
I.e., for an enum declared as:
enum Permissions : ulong
{
None,
Read,
Write,
Full
}
You would use:
var permissions1 = Permissions.None;
var permissions2 = Permissions.Full;
var maxPermission = (Permissions) Math.Max((ulong) permissions1, (ulong) permissions2);
can be called with 2 or more parameters
public static T GetMaxEnum<T>(params T[] enums) where T : struct, IConvertible
{
if (enums.Length < 2)
{
throw new InvalidEnumArgumentException();
}
return enums.Max();
}
This is what I came up with because I couldn't find anything in .NET that did this.
public static class EnumHelper
{
public static T Min<T>(T a, T b)
{
return (dynamic)a < (dynamic)b ? a : b;
}
public static T Max<T>(T a, T b)
{
return (dynamic)a > (dynamic)b ? a : b;
}
}
While this question is quite old, it shows up at the top for some searches I did, so here we go, with a little more detail than the existing answer:
Permissions p1 = Permissions.Read;
Permissions p2 = Permissions.Write;
var pMax = (Permissions)Math.Max( (int)p1, (int)p2 );
Alternatively in case the enum is long based:
var pMax = (Permissions)Math.Max( (long)p1, (long)p2 );
Why does this work?
enum values can be cast to int (or 'long'), which represents their position
An int can be cast back to an enum
Math.Max() apparently works on int
Sidenotes:
Appearently this also works for the mininum with Math.Min()
IEnumerable.Max() and IEnumerable.Min() can be used if you need the maximum or minimum of more than two enum values (if you don't mind System.Linq).
I think you want something like this:
public enum Enum1
{
A_VALUE,
B_VALUE,
C_VALUE
}
public enum Enum2
{
VALUE_1,
VALUE_2,
VALUE_3
}
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Console.WriteLine(p.EnumMin<Enum1>());
Console.WriteLine(p.EnumMax<Enum2>());
}
T EnumMin<T>()
{
T ret; ;
Array x = Enum.GetValues(typeof(T));
ret = (T) x.GetValue(0);
return ret;
}
T EnumMax<T>()
{
T ret; ;
Array x = Enum.GetValues(typeof(T));
ret = (T)x.GetValue(x.Length-1);
return ret;
}
}
There is a one-stop means for getting the min and max for any enumeration. All it assumes is that the representation type is an int.
public Tuple<int,int> GetMinMaxOfEnumeration<T>()
{
if (!typeof (T).IsEnum)
{
throw new ArgumentException("Type must be an enumeration");
}
var valuesAsInt = Enum.GetValues(typeof (T)).Cast<int>().OrderBy(n => n).ToArray();
return new Tuple<int, int>(valuesAsInt.First(), valuesAsInt.Last());
}

String to numeric conversion in c#

I am trying to write a function to convert the contents of a string "12345" to an int.
If the string is blank i would like to return null (uninitialized), not the value 0.
Problem is, functions do not return un-initialized values.
My code will not compile as Retval can return an uninitialized value......
My attempt so far:
public int ConvertStringToNumber(String TheString)
{
// Uninitialized
int Retval;
if (TheString.Length > 0)
{
// We have a valid string
if (Int32.TryParse(TheString, out Retval))
{
// We have a valid Number
}
}
// Return the number or null
return Retval;
}
Can you use Nullable int ? it will allow set as nullable . See here : http://www.codeproject.com/Articles/11854/C-2-0-Nullable-Types
You can use a nullable int (more info here).
Nullable types can represent all the values of an underlying type, and
an additional null value.
public int? ConvertStringToNumber(String TheString)
{
int retval;
bool isInt = Int32.TryParse(TheString, out retval);
return isInt ? retval : null;
}
Note: When using nullable types, you'll need to use a cast or get it's value. See here.
Example:
int? n = ConvertStringToNumber("123");
int value = n.Value;
// or
int value = (int)n;
If you assigned a value to the Retval object AT THE FIRST TIME, then the value is valid in THAT area ONLY.
So, Retval is null when you return it.
since Int32.TryParse(TheString, out Retval) require int type not nullable
public int? ConvertStringToNumber(String TheString)
{
// Uninitialized
int Retval;
if (TheString.Length > 0)
{
// We have a valid string
if (Int32.TryParse(TheString, out Retval))
{
// We have a valid Number
return Retval;
}
}
// Return the number or null
return null;
}
Simple extension method to resolve your problem
using System;
namespace temp
{
class Program
{
static void Main(string[] args)
{
string valu = "";
Console.WriteLine(valu.ToInt32());
Console.ReadLine();
}
}
public static class MyExtentions
{
public static int ToInt32(this string s)
{
int x;
if (s != null)
{
if (s.Length > 1)
x = Convert.ToInt32(s);
else
x = 0;
}
else
{
x= 0;
}
return x;
}
}
}
int? x = ConvertStringToNumber("1");
int value = x.Value;
String to numeric conversion in c#

Datatypes in 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');

Categories