C# Without the Noise
I've been toying around with the idea on removing (what I perceive) as clutter and noise from C#.
Happened looking at the Money Type for the CLR project and thought it would be good example to see what affect it had.
Original
The Decluttering Begins
Conclusions
The Good:
In terms of line count it about a third of the size
I like the clean look.
The Bad: Under the current version properties aren't
Possible fix is to introduce a new Properties modifier
I've been toying around with the idea on removing (what I perceive) as clutter and noise from C#.
Happened looking at the Money Type for the CLR project and thought it would be good example to see what affect it had.
Original
using System; namespace System { public struct Money : IEquatable<Money>, IComparable<Money>, IFormattable, IConvertible { public static implicit operator Money(Byte value) { return new Money((Decimal)value); } public static implicit operator Money(SByte value) { return new Money((Decimal)value); } public static implicit operator Money(Single value) { return new Money((Decimal)value); } public static implicit operator Money(Double value) { return new Money((Decimal)value); } public static implicit operator Money(Decimal value) { return new Money(value); } public static implicit operator Decimal(Money value) { return value.computeValue(); } public static implicit operator Money(Int16 value) { return new Money((Decimal)value); } public static implicit operator Money(Int32 value) { return new Money((Decimal)value); } public static implicit operator Money(Int64 value) { return new Money((Decimal)value); } public static implicit operator Money(UInt16 value) { return new Money((Decimal)value); } public static implicit operator Money(UInt32 value) { return new Money((Decimal)value); } public static implicit operator Money(UInt64 value) { return new Money((Decimal)value); } public static Money operator -(Money value) { return new Money(-value._units, -value._decimalFraction, value._currency); } public static Money operator +(Money left, Money right) { if (left.Currency != right.Currency) throw differentCurrencies(); Int32 fractionSum = left._decimalFraction + right._decimalFraction; Int64 overflow = 0; Int32 fractionSign = Math.Sign(fractionSum); Int32 absFractionSum = Math.Abs(fractionSum); if (absFractionSum >= FractionScale) { overflow = fractionSign; absFractionSum -= (Int32)FractionScale; fractionSum = fractionSign * absFractionSum; } Int64 newUnits = left._units + right._units + overflow; if (fractionSign < 0 && Math.Sign(newUnits) > 0) { newUnits -= 1; fractionSum = (Int32)FractionScale - absFractionSum; } return new Money(newUnits, fractionSum, left.Currency); } public static Money operator -(Money left, Money right) { if (left.Currency != right.Currency) throw differentCurrencies(); return left + -right; } public static Money operator *(Money left, Decimal right) { return ((Decimal)left * right); } public static Money operator /(Money left, Decimal right) { return ((Decimal)left / right); } public static Boolean operator ==(Money left, Money right) { return left.Equals(right); } public static Boolean operator !=(Money left, Money right) { return !left.Equals(right); } public static Boolean operator >(Money left, Money right) { return left.CompareTo(right) > 0; } public static Boolean operator <(Money left, Money right) { return left.CompareTo(right) < 0; } public static Boolean operator >=(Money left, Money right) { return left.CompareTo(right) >= 0; } public static Boolean operator <=(Money left, Money right) { return left.CompareTo(right) <= 0; } private const Decimal FractionScale = 1E9M; private readonly Currency _currency; private readonly Int64 _units; private readonly Int32 _decimalFraction; public Money(Decimal value) { checkValue(value); _units = (Int64)value; _decimalFraction = (Int32)Decimal.Round((value - _units) * FractionScale); if (_decimalFraction >= FractionScale) { _units += 1; _decimalFraction = _decimalFraction - (Int32)FractionScale; } _currency = Currency.FromCurrentCulture(); } public Money(Decimal value, Currency currency) : this(value) { _currency = currency; } private Money(Int64 units, Int32 fraction, Currency currency) { _units = units; _decimalFraction = fraction; _currency = currency; } public override Int32 GetHashCode() { return 207501131 ^ _units.GetHashCode() ^ _currency.GetHashCode(); } public override Boolean Equals(Object obj) { if (!(obj is Money)) { return false; } Money other = (Money)obj; return Equals(other); } public override String ToString() { return computeValue().ToString("C"); } public String ToString(String format) { return computeValue().ToString(format); } public Currency Currency { get { return _currency; } } #region Implementation of IEquatable<Money> public Boolean Equals(Money other) { checkCurrencies(other); return _units == other._units && _decimalFraction == other._decimalFraction; } #endregion #region Implementation of IComparable<Money> public Int32 CompareTo(Money other) { checkCurrencies(other); Int32 unitCompare = _units.CompareTo(other._units); return unitCompare == 0 ? _decimalFraction.CompareTo(other._decimalFraction) : unitCompare; } #endregion #region Implementation of IFormattable public String ToString(String format, IFormatProvider formatProvider) { return computeValue().ToString(format, formatProvider); } #endregion #region Implementation of IConvertible public TypeCode GetTypeCode() { return TypeCode.Object; } public Boolean ToBoolean(IFormatProvider provider) { return _units == 0 && _decimalFraction == 0; } public Char ToChar(IFormatProvider provider) { throw new NotSupportedException(); } public SByte ToSByte(IFormatProvider provider) { return (SByte)computeValue(); } public Byte ToByte(IFormatProvider provider) { return (Byte)computeValue(); } public Int16 ToInt16(IFormatProvider provider) { return (Int16)computeValue(); } public UInt16 ToUInt16(IFormatProvider provider) { return (UInt16)computeValue(); } public Int32 ToInt32(IFormatProvider provider) { return (Int32)computeValue(); } public UInt32 ToUInt32(IFormatProvider provider) { return (UInt32)computeValue(); } public Int64 ToInt64(IFormatProvider provider) { return (Int64)computeValue(); } public UInt64 ToUInt64(IFormatProvider provider) { return (UInt64)computeValue(); } public Single ToSingle(IFormatProvider provider) { return (Single)computeValue(); } public Double ToDouble(IFormatProvider provider) { return (Double)computeValue(); } public Decimal ToDecimal(IFormatProvider provider) { return computeValue(); } public DateTime ToDateTime(IFormatProvider provider) { throw new NotSupportedException(); } public String ToString(IFormatProvider provider) { return ((Decimal)this).ToString(provider); } public Object ToType(Type conversionType, IFormatProvider provider) { throw new NotSupportedException(); } #endregion private Decimal computeValue() { return _units + _decimalFraction / FractionScale; } private static Exception differentCurrencies() { return new InvalidOperationException("Money values are in different " + "currencies. Convert to the same " + "currency before performing " + "operations on the values."); } private static void checkValue(Decimal value) { if (value < Int64.MinValue || value > Int64.MaxValue) { throw new ArgumentOutOfRangeException("value", value, "Money value must be between " + Int64.MinValue + " and " + Int64.MaxValue); } } private void checkCurrencies(Money other) { if (other.Currency != Currency) { throw differentCurrencies(); } } } }
The Decluttering Begins
- General Appearence
- What if C# was line-orientated? So the semi-colon ; on the end of statement is no longer needed.
- Indentation is equivalent using { } or scoping, modifier and return type are inherited by descendant indentations.
- Code Folding will available at the start indentation to the end of the indentation.
Interfaces - <-- Interface is been implemented.
- return types on interface implementation are not needed, because they come from the template, and can't methods can not be differentiated on return type anyway.
Statically Check Interpolation - $@ Type-Safe and statically checked string interpolation, which means what ever is in braces is check to see if it is visible.
Copy-Cat Typing - (Money left right) Type from the previous is used for type of the next parameter. If the parameter is a different type the parameter must be preceeded by a comma before the type.
using System; namespace System public struct Money Implements IEquatable<Money>y IComparable<Money> IFormattable IConvertible private static Exception differentCurrencies() return new InvalidOperationException("Money values are in different currencies. Convert to the same currency before performing operations on the values."); void checkValue(Decimal value) if (value < Int64.MinValue || value > Int64.MaxValue) throw new ArgumentOutOfRangeException("value", value, $@"Money value must be between ${Int64.MinValue} and ${Int64.MaxValue}") Money (Decimal value) checkValue(value) _units = (Int64)value _decimalFraction = (Int32)Decimal.Round((value - _units) * FractionScale) if (_decimalFraction >= FractionScale) _units++ _decimalFraction = _decimalFraction - (Int32)FractionScale _currency = Currency.FromCurrentCulture() (Decimal value, Currency currency) : this(value) _currency = currency (Int64 units, Int32 fraction, Currency currency) _units = units _decimalFraction = fraction _currency = currency const Decimal FractionScale = 1E9M readonly Currency _currency Int64 _units Int32 _decimalFraction Decimal computeValue() return (_units + _decimalFraction) / FractionScale void checkCurrencies(Money other) if (other.Currency != Currency) throw differentCurrencies() public override Int32 GetHashCode() return 207501131 ^ _units.GetHashCode() ^ _currency.GetHashCode() Boolean Equals(Object obj) if (!(obj is Money)) return false Money other = (Money)obj return Equals(other) String ToString() return computeValue().ToString("C") String ToString(String format) return computeValue().ToString(format) Currency Currency get: return _currency <-- IEquatable<Money> Equals(Money other) checkCurrencies(other) return (_units == other._units) && (_decimalFraction == other._decimalFraction) <-- IComparable<Money> CompareTo(Money other) checkCurrencies(other) Int32 unitCompare = _units.CompareTo(other._units) return unitCompare == 0 ? _decimalFraction.CompareTo(other._decimalFraction) : unitCompare <-- IFormattable ToString(String format, IFormatProvider formatProvider) return computeValue().ToString(format, formatProvider) <-- ICovertable GetTypeCode () return TypeCode.Object ToBoolean (IFormatProvider provider) return (_units == 0) && (_decimalFraction == 0) ToChar (IFormatProvider provider) throw new NotSupportedException() ToSByte (IFormatProvider provider) return (SByte) computeValue() ToByte (IFormatProvider provider) return (Byte) computeValue() ToInt16 (IFormatProvider provider) return (Int16) computeValue() ToUInt16 (IFormatProvider provider) return (UInt16) computeValue() ToInt32 (IFormatProvider provider) return (Int32) computeValue() ToUInt32 (IFormatProvider provider) return (UInt32) computeValue() ToInt64 (IFormatProvider provider) return (Int64) computeValue() ToUInt64 (IFormatProvider provider) return (UInt64) computeValue() ToSingle (IFormatProvider provider) return (Single) computeValue() ToDouble (IFormatProvider provider) return (Double) computeValue() ToDecimal (IFormatProvider provider) return computeValue() ToDateTime (IFormatProvider provider) throw new NotSupportedException() ToString (IFormatProvider provider) return ((Decimal)this).ToString(provider) ToType (Type conversionType, IFormatProvider provider) throw new NotSupportedException() static operator implicit Decimal(Money value) return value.computeValue() Money (Byte value) return new Money((Decimal)value) (SByte value) return new Money((Decimal)value) (Single value) return new Money((Decimal)value) (Double value) return new Money((Decimal)value) (Decimal value) return new Money(value) (Int16 value) return new Money((Decimal)value) (Int32 value) return new Money((Decimal)value) (Int64 value) return new Money((Decimal)value) (UInt16 value) return new Money((Decimal)value) (UInt32 value) return new Money((Decimal)value) (UInt64 value) return new Money((Decimal)value) Money - (Money value) return new Money(-value._units, -value._decimalFraction, value._currency) + (Money left right) if (left.Currency != right.Currency) throw differentCurrencies() Int32 fractionSum = left._decimalFraction + right._decimalFraction Int64 overflow = 0; Int32 fractionSign = Math.Sign(fractionSum) Int32 absFractionSum = Math.Abs(fractionSum) if (absFractionSum >= FractionScale) overflow = fractionSign absFractionSum -= (Int32)FractionScale fractionSum = fractionSign * absFractionSum Int64 newUnits = left._units + right._units + overflow if (fractionSign < 0 && Math.Sign(newUnits) > 0) newUnits -= 1 fractionSum = (Int32)FractionScale - absFractionSum return new Money(newUnits, fractionSum, left.Currency) - (Money left right) if (left.Currency != right.Currency) throw differentCurrencies() return left + -right * (Money left, Decimal right) return ((Decimal)left * right) / (Money left, Decimal right) return ((Decimal)left / right) Boolean == (Money left right) return left.Equals(right) != (Money left right) return !left.Equals(right) > (Money left right) return left.CompareTo(right) > 0 < (Money left right) return left.CompareTo(right) < 0 >= (Money left right) return left.CompareTo(right) >= 0 <= (Money left right) return left.CompareTo(right) <= 0
Conclusions
The Good:
In terms of line count it about a third of the size
I like the clean look.
The Bad: Under the current version properties aren't
String ToString(String format) return computeValue().ToString(format) Currency Currency get: return _currency <-- IEquatable<Money>
Possible fix is to introduce a new Properties modifier
String ToString(String format) return computeValue().ToString(format) Properties Currency Currency get: return _currency <-- IEquatable<Money>
1 Comments On This Entry
Page 1 of 1

Braber01
16 April 2012 - 04:34 PM
You should check out the Boo.Net Extension it's kind of like this however it's mostly python syntax but I think you'll be happy with it
Page 1 of 1
Search My Blog
Recent Entries
Recent Comments
0 user(s) viewing
0 Guests
0 member(s)
0 anonymous member(s)
0 member(s)
0 anonymous member(s)
← February 2019 →
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 |
Tags
- .net
- .net4
- bf
- brainfuck
- Codeplex
- Coding
- custom Control
- custom controls
- DIC CodeAID VS Gallery
- Dice
- Die
- DLL
- Englishify
- Extension
- Extension Method
- ExtMethods
- F#
- Functional
- Functional Programming
- Graph
- Graphs
- Language Intergrated Query.
- Library
- LINQ
- LINQ Codes
- LISP interpreter
- Macro
- My Games
- Nemerle.
- net
- podcast
- Project
- Project Cider
- RadixSort Generics (Of T)
- restricted textbox
- Rolling
- rss
- rss feed
- Scribblings
- shadowtext
- Tips
- Transparent Textbox
- vb
- vb.net
- VB.net +LINQ Extension Method
- vb.net 1-Liners
- vb.net visual basic vs2010 .net4
- vs2010
- Weird
- XM
- xml
- XML Literals