Skip to main content
Code Review

Return to Question

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
added 2488 characters in body
Source Link
DLeh
  • 300
  • 3
  • 11

Below is a simplified example that can be run in LinqPad that shows the issue.

void Main()
{
 var immutable = new MyImmutable(new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, -5 },
 { ImmutableKey.Key3, 1.25m },
 });
 
 var immutable2 = new MyImmutable(new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, 2 },
 { ImmutableKey.Key3, 3 },
 });
 
 var added = immutable.Apply((a, b) => a + b, immutable2);
 added[ImmutableKey.Key1].Dump();
 added[ImmutableKey.Key2].Dump();
 added[ImmutableKey.Key3].Dump();
 
 var subImmutable1 = new SubImmutable(1, new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, -5 },
 { ImmutableKey.Key3, 1.25m },
 });
 var subImmutable2 = new SubImmutable(1, new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, 2 },
 { ImmutableKey.Key3, 3 },
 });
 
 var subImmutableAdded = subImmutable1.Apply((a, b) => a + b, subImmutable2);
 subImmutableAdded.GetType().Name.Dump(); //prints MyImmutable, it's not a SubImmutable
 //after adding two SubImmutables, the type is changed back to the base type
 
 var asSub = (SubImmutable)subImmutableAdded; // Unable to cast object of type 'MyImmutable' to type 'SubImmutable', SomeOtherValue was lost.
}
public enum ImmutableKey 
{
 Key1,
 Key2,
 Key3
}
public class MyImmutable
{
 protected static readonly IEnumerable<ImmutableKey> AllKeys = Enum.GetValues(typeof(ImmutableKey)).Cast<ImmutableKey>();
 
 private Dictionary<ImmutableKey, decimal> _dict { get; set; }
 
 public MyImmutable(Dictionary<ImmutableKey,decimal> d)
 {
 _dict = d;
 }
 
 public decimal this[ImmutableKey key]
 {
 get
 {
 if (_dict == null || !_dict.ContainsKey(key))
 return 0;
 return _dict[key];
 }
 }
 
 public MyImmutable Apply(Func<decimal, decimal, decimal> aggFunc, MyImmutable y)
 {
 var aggregated = new Dictionary<ImmutableKey, decimal>(AllKeys.Count());
 foreach (ImmutableKey bt in AllKeys)
 {
 aggregated[bt] = aggFunc(this[bt], y[bt]);
 }
 return new MyImmutable(aggregated);
 }
}
public class SubImmutable : MyImmutable
{
 public int SomeOtherValue { get; set; }
 public SubImmutable(int someValue, Dictionary<ImmutableKey,decimal> d)
 :base(d)
 {
 SomeOtherValue= someValue;
 }
}

Companion SO question: http://stackoverflow.com/questions/28326884/c-sharp-immutable-class-sub-class

Below is a simplified example that can be run in LinqPad that shows the issue.

void Main()
{
 var immutable = new MyImmutable(new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, -5 },
 { ImmutableKey.Key3, 1.25m },
 });
 
 var immutable2 = new MyImmutable(new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, 2 },
 { ImmutableKey.Key3, 3 },
 });
 
 var added = immutable.Apply((a, b) => a + b, immutable2);
 added[ImmutableKey.Key1].Dump();
 added[ImmutableKey.Key2].Dump();
 added[ImmutableKey.Key3].Dump();
 
 var subImmutable1 = new SubImmutable(1, new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, -5 },
 { ImmutableKey.Key3, 1.25m },
 });
 var subImmutable2 = new SubImmutable(1, new Dictionary<ImmutableKey, decimal>{
 { ImmutableKey.Key1, 1 },
 { ImmutableKey.Key2, 2 },
 { ImmutableKey.Key3, 3 },
 });
 
 var subImmutableAdded = subImmutable1.Apply((a, b) => a + b, subImmutable2);
 subImmutableAdded.GetType().Name.Dump(); //prints MyImmutable, it's not a SubImmutable
 //after adding two SubImmutables, the type is changed back to the base type
 
 var asSub = (SubImmutable)subImmutableAdded; // Unable to cast object of type 'MyImmutable' to type 'SubImmutable', SomeOtherValue was lost.
}
public enum ImmutableKey 
{
 Key1,
 Key2,
 Key3
}
public class MyImmutable
{
 protected static readonly IEnumerable<ImmutableKey> AllKeys = Enum.GetValues(typeof(ImmutableKey)).Cast<ImmutableKey>();
 
 private Dictionary<ImmutableKey, decimal> _dict { get; set; }
 
 public MyImmutable(Dictionary<ImmutableKey,decimal> d)
 {
 _dict = d;
 }
 
 public decimal this[ImmutableKey key]
 {
 get
 {
 if (_dict == null || !_dict.ContainsKey(key))
 return 0;
 return _dict[key];
 }
 }
 
 public MyImmutable Apply(Func<decimal, decimal, decimal> aggFunc, MyImmutable y)
 {
 var aggregated = new Dictionary<ImmutableKey, decimal>(AllKeys.Count());
 foreach (ImmutableKey bt in AllKeys)
 {
 aggregated[bt] = aggFunc(this[bt], y[bt]);
 }
 return new MyImmutable(aggregated);
 }
}
public class SubImmutable : MyImmutable
{
 public int SomeOtherValue { get; set; }
 public SubImmutable(int someValue, Dictionary<ImmutableKey,decimal> d)
 :base(d)
 {
 SomeOtherValue= someValue;
 }
}

Companion SO question: http://stackoverflow.com/questions/28326884/c-sharp-immutable-class-sub-class

added 189 characters in body
Source Link
DLeh
  • 300
  • 3
  • 11

If you'd like to run this code, I believe that the ImmutableDictionary is the only type that requires a non-standard library. You should be able to swap it with a normal Dictionary.

If you'd like to run this code, I believe that the ImmutableDictionary is the only type that requires a non-standard library. You should be able to swap it with a normal Dictionary.

deleted 38 characters in body
Source Link
DLeh
  • 300
  • 3
  • 11
Loading
deleted 38 characters in body
Source Link
DLeh
  • 300
  • 3
  • 11
Loading
added 1107 characters in body
Source Link
DLeh
  • 300
  • 3
  • 11
Loading
Source Link
DLeh
  • 300
  • 3
  • 11
Loading
lang-cs

AltStyle によって変換されたページ (->オリジナル) /