Why I can't change an array element obtained from another class? - c#

I created a class that implements the wrapper over the array double [] but I can not change the element of the received array. These are tests
public void SetCorrectly ()
public void IndexerDoesNotCopyArray ()
The problem sounds like this. Write the class Indexer, which is created as a wrapper over the array double [], and opens access to its subarray of some length, starting with some element. Your decision must pass the tests contained in the project. As always, you must monitor the integrity of the data in Indexer.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Incapsulation.Weights
{
public class Indexer
{
double[] array;
int start;
int length;
public int Length
{
get { return length; }
}
public Indexer(double[] array, int start, int length)
{
if (start < 0 || start >= array.Length) throw new ArgumentException();
this.start = start;
if (length < start || length > array.Length) throw new ArgumentException();
this.length = length;
this.array = array.Skip(start).Take(length).ToArray();
}
public double this[int index]
{
get { return array[index]; }
set { array[index] = value; }
}
}
}
This is tests
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Incapsulation.Weights
{
[TestFixture]
public class Indexer_should
{
double[] array = new double[] { 1, 2, 3, 4 };
[Test]
public void HaveCorrectLength()
{
var indexer = new Indexer(array, 1, 2);
Assert.AreEqual(2, indexer.Length);
}
[Test]
public void GetCorrectly()
{
var indexer = new Indexer(array, 1, 2);
Assert.AreEqual(2, indexer[0]);
Assert.AreEqual(3, indexer[1]);
}
[Test]
public void SetCorrectly()
{
var indexer = new Indexer(array, 1, 2);
indexer[0] = 10;
Assert.AreEqual(10, array[1]);
}
[Test]
public void IndexerDoesNotCopyArray()
{
var indexer1 = new Indexer(array, 1, 2);
var indexer2 = new Indexer(array, 0, 2);
indexer1[0] = 100500;
Assert.AreEqual(100500, indexer2[1]);
}
}

The problem you are facing here is that the last test requires that your wrapper provides access to the underlying array. In other words, whatever number of Indexers are created, they all point to the same underlying array.
Your line here this.array = array.Skip(start).Take(length).ToArray(); violates this requirement creating a new instance of Array class. Because of this the value changed by first indexer is not reflected in the second one - they point to different memory areas.
To fix this, instead of creating a new Array using LINQ, simply store the original array passed through constructor. Your this[] indexer property must take care of passed start and end adding start to the index and checking the out-of-boundaries condition manually.

All linq extension methods create a new enumeration, they do not mutate or return the one the method is called on:
var newArray = array.Skip(...).ToArray();
ReferenceEquals(array, newArray); //returns false
Any change you might make in an element of newArray will not change anything whatsoever in array.
Your SetCorrectly test is comparing indexer and array and it will always fail. Your other test also fails because indexer1 and indexer2 reference two different arrays.
However because Linq is lazy, modifying array can be seen by the result of the Linq extension method depending on when you materialize the enumeration; this can happen:
var skippedA = array.Skip(1); //deferred execution
array[1] = //some different value...,
var newArray =skipped.ToArray(); //Skip is materialized here!
newArray[1] == array[1]; //true!

Related

Returning an Array Manipulates Original Value in C#

This is my first question on the site and I am sure I'll find my answer here.
For school, I was trying to do some basic C# coding for a challenge that was given to us.
Here is the problem:
Normally when I pass a value through a method I don't run into issues. Like so:
static void Main(string[] args)
{
// Declare Integer
int originalInt = 20;
// Call the Method
int multipliedInt = Multiplication(originalInt);
// Prompt
Console.WriteLine("Original: {0} Modified: {1}", originalInt, multipliedInt);
}
// Method
static public int Multiplication(int original)
{
// Quik Maffs
int modifiedValue = original * 2;
return modifiedValue;
}
The above example works just fine. The original value is 20 and the modified value is 40.
However, this changes when I attempt to do that with an array:
static void Main(string[] args)
{
// Declare Original Array
int[] originalArray = new int[] {1, 4, 6, 8, 12};
// Call Method
int[] multipliedArray = Multiplication(originalArray);
// Prompt
Console.WriteLine("Original: [{0}], Multiplied: [{1}]", String.Join(", ", originalArray), String.Join(", ", multipliedArray));
}
// Method
static public int[] Multiplication(int[] original)
{
// New Int
int[] modified = original;
// Loop
for (int i = 0; i < modified.Length; i++)
{
modified[i] *= 2;
}
return modified;
}
The code above returned the modified value twice. It seems like it modifies the original value as well.
Any idea why this is happening?
int is a value type. When you pass a value type to a method, you pass a copy of the value.
Arrays are reference types. When you pass a reference type to a method, you pass a copy of the reference... but both the copy and original still refer to the same object.
Now it seems you may have understood this much, because of this code:
(This is why I re-opened the question... the stock ref-vs-value answer wasn't gonna cut it here)
int[] modified = original;
However, the other thing that happens with reference types is assignments also only copy the reference. So modified and original in that snippet again refer to the same array object.
To fix this, you need to make an actual deep copy of the array. There are several ways to do this. I would tend to write the method this way:
static public IEnumerable<int> Multiplication(IEnumerable<int> original)
{
return original.Select(i => i * 2);
}
...and append a .ToArray() at the end of the method call if and only if I really need a full array (hint: very often it turns out you don't), like this:
int[] multipliedArray = Multiplication(originalArray).ToArray();
or like this:
var multipliedArray = Multiplication(originalArray);
But I understand there are a number of things here that aren't very familiar to a beginner. You might try something more like this:
static public int[] Multiplication(int[] original)
{
int[] modifed = new int[original.Length];
for (int i = 0; i < original.Length; i++)
{
modified[i] = original[i] * 2;
}
return modified;
}

Parallel.Foreach with modulo partitioning

When using Parallel.Foreach() for 100 items using 4 threads, it will divide the list into 4 blocks (0-24,25-49,50-74,75-99) of items, which means, that items 0, 25, 50 and 75 are processed in parallel.
Is it somehow possible to partition the items in a modulo way to handle those with lower indices first? Like:
Thread 1: 0, 5, 9,..
Thread 2: 1, 6, 10,...
Thread 3: 2, 7, 11,...
Thread 4: 3, 8, 12,...
This partitioning method is known as Round Robin, or Striping. The primary challenge of using this with Parallel.ForEach() is that ForEach() requires partitioners to support dynamic partitions, which would not be possible with this type of partitioning as the number of partitions must be fixed prior to execution of the loop.
One way to achieve this type of partitioning is to create a custom class derived from System.Collections.Concurrent.Partitioner<TSource> and use the ParallelQuery.ForAll() method, which does not have the dynamic partitioning support requirement. For most applications this should be equivalent to using ForEach().
Below is an example of a custom Partitioner and a basic implementation. The Partitioner will generate the same number of partitions as the degree of parallelism.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace RoundRobinPartitioning
{
public class RoundRobinPartitioner<TSource> : Partitioner<TSource>
{
private readonly IList<TSource> _source;
public RoundRobinPartitioner(IList<TSource> source)
{
_source = source;
}
public override bool SupportsDynamicPartitions { get { return false; } }
public override IList<IEnumerator<TSource>> GetPartitions(int partitionCount)
{
var enumerators = new List<IEnumerator<TSource>>(partitionCount);
for (int i = 0; i < partitionCount; i++)
{
enumerators.Add(GetEnumerator(i, partitionCount));
}
return enumerators;
}
private IEnumerator<TSource> GetEnumerator(
int partition,
int partitionCount)
{
int position = partition;
TSource value;
while (position < _source.Count)
{
value = _source[position];
position += partitionCount;
yield return value;
}
}
}
class Program
{
static void Main(string[] args)
{
var values = Enumerable.Range(0, 100).ToList();
var partitioner = new RoundRobinPartitioner<int>(values);
partitioner.AsParallel()
.WithDegreeOfParallelism(4)
.ForAll(value =>
{
// Perform work here
});
}
}
}

Generic Mergesort in C#

I am trying to implement a generic Mergesort algorithm in C#, but I am having difficulty with the Constraints. I have searched many references but I can't find any that are implementing the algorithm like I am.
MergeSort algorithm in C#
Generic Implementation of Sorting Algorithms
Anyways, I am trying to provide an implementation that only allows the user to Mergesort a dataset that inherits from the IComparable interface.
Below is what I have so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SortUtil
{
class Program
{
static void Main(string[] args)
{
List<int> testList = new List<int> { 1, 5, 2, 7, 3, 9, 4, 6 };
Mergesort.mergeSort<int>(testList); // Compiler Error at this Line.
}
}
class Mergesort
{
public static void mergeSort<T>(ref List<T> inputData)
where T: IComparable<T>
{
mergeSort(ref inputData, 0, inputData.Count - 1);
}
private static void mergeSort<T>(ref List<T> inputData, int firstIndex, int lastIndex)
where T: IComparable<T>
{
// If the firstIndex is greater than the lastIndex then the recursion
// has divided the problem into a single item. Return back up the call
// stack.
if (firstIndex >= lastIndex)
return;
int midIndex = (firstIndex + lastIndex) / 2;
// Recursively divide the first and second halves of the inputData into
// its two seperate parts.
mergeSort(ref inputData, firstIndex, midIndex);
mergeSort(ref inputData, midIndex + 1, lastIndex);
// Merge the two remaining halves after dividing them in half.
merge(ref inputData, firstIndex, midIndex, lastIndex);
}
private static void merge<T>(ref List<T> inputData, int firstIndex, int midIndex, int lastIndex)
where T: IComparable<T>
{
int currentLeft = firstIndex;
int currentRight = midIndex + 1;
T[] tempData = new T[(lastIndex - firstIndex) + 1];
int tempPos = 0;
// Check the items at the left most index of the two havles and compare
// them. Add the items in ascending order into the tempData array.
while (currentLeft <= midIndex && currentRight <= lastIndex)
if (inputData.ElementAt(currentLeft).CompareTo(inputData.ElementAt(currentRight)) < 0)
{
tempData[tempPos++] = inputData.ElementAt(currentLeft++);
}
else
{
tempData[tempPos++] = inputData.ElementAt(currentRight++);
}
// If there are any remaining items to be added to the tempData array,
// add them.
while (currentLeft <= midIndex)
{
tempData[tempPos++] = inputData.ElementAt(currentLeft++);
}
while (currentRight <= lastIndex)
{
tempData[tempPos++] = inputData.ElementAt(currentRight++);
}
// Now that the items have been sorted, copy them back into the inputData
// reference that was passed to this function.
tempPos = 0;
for (int i = firstIndex; i <= lastIndex; i++) {
inputData.Insert(firstIndex, tempData.ElementAt(tempPos));
}
}
}
}
My issue: I am getting a Compiler error in the Main method of the Program class; however, shouldn't I have to supply the mergeSort function the parametrized type when I call it statically?
I am getting the error "The best overloaded method match for... has some invalid arguments."
I would greatly appreciate any implementation suggestions and/or any way of correcting this error. Note, I am most comfortable in Java, and since C# doesn't directly support wildcards this approach is foreign to me. Any explanations on this would be appreciated as well.
You could remove ref from all of your parameters since you do not seem to be using its functionality.
Also you would not need to provide generic parameter type in most cases because the compiler will infer the type for you. So this should work (assuming you've removed ref from the parameters) in most cases:
Mergesort.mergeSort(testList);
Also List<T> and arrays have indexers so you can get at specific elements via inputData[index] instead of ElementAt. It's just less typing that way.
MergeSort reuires a ref parameter, so it needs the ref keyword. This should work:
Mergesort.mergeSort<int>(ref testList);
The ref keyword causes an argument to be passed by reference, not by
value. The effect of passing by reference is that any change to the
parameter in the method is reflected in the underlying argument
variable in the calling method. The value of a reference parameter is
always the same as the value of the underlying argument variable.

C# change some parts of code in method automatically (programmatically?)

I use this method called SearchConsequences to iterate through List<ValuesEO> of objects and perform some tasks, for getting values of particular fields, according to applied rules. I want to somehow simplify this code.
I want to switch (replace) everywhere in code the expression ValuesEO[i].powerR for other ValuesEO[i].otherField in the whole block of code.
At this time I do this just by block coping and changing it manually. So lets say, at the end, I have 5 blocks of really similar code blocks in this method. The only difference is in ValuesEO[i].otherField than ValuesEO[i].otherField2 ValuesEO[i].otherField3 ... and so on.
I don't like that block coping.
public Dictionary<Consequence,Cause> SearchConsequences(List<ResultsCatcher> smallTable, int n, ConnectHYSYS obj, int keyP, int keyR)//for one stream for one parameter
{
double threshold = 0.005;
Dictionary<Consequence,Cause> collection = new Dictionary<Consequence,Cause>();
//search in ValesE for each energy stream, for powerR
for (int i = 0; i < smallTable[n].ValuesE.Count; i++)
{
//sort the smallTable
smallTable.Sort((x, y) => x.ValuesE[i].powerR.CompareTo(y.ValuesE[i].powerR));
//get the index of first occurrence of powerR >= threshold, if there is nothing bigger than threshold, index is null
var tagged = smallTable.Select((item, ii) => new { Item = item, Index = (int?)ii });
int? index = (from pair in tagged
where pair.Item.ValuesE[i].powerR >= threshold
select pair.Index).FirstOrDefault();
//get needed information
if (index != null)
{
int id = Convert.ToInt16(index);
double newValue = smallTable[id].ValuesE[i].power;
double newValueR = smallTable[id].ValuesE[i].powerR;
TypeOfValue kindOf = TypeOfValue.power;
Consequence oneConsequence = new Consequence(obj.EnergyStreamsList[i], newValue, newValueR, kindOf);
Cause oneCause = new Cause();
oneCause.GetTableHeader(smallTable[id]);
collection.Add(oneConsequence,oneCause);
}
}
}
Maybe it is easy to accomplish that and somewhere this problem is discussed.
But I really even don't know how to google it.
This is a ready made program for you that demonstrates how to move your criteria/property selection outside your examination function. Have a look to see how fields criterias are matched.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
namespace Test
{
class Program
{
public class PowerValues
{
public double power;
public double powerR;
public double lightbulbs;
public double lightbulbsR;
}
public static void DoSomething(IEnumerable<PowerValues> powerValues, Func<PowerValues, double> criteria, double treshhold)
{
var flaggedElements = powerValues.Where(e => criteria(e) > treshhold);
foreach (var flagged in flaggedElements)
{
Console.WriteLine("Value flagged: {0}", criteria(flagged));
}
}
public static void Main(string[] args)
{
List<PowerValues> powerValues = new List<PowerValues>();
powerValues.Add(new PowerValues(){power=10, powerR=0.002, lightbulbs = 2, lightbulbsR = 2.006});
powerValues.Add(new PowerValues(){power=5, powerR=0.004, lightbulbs = 4, lightbulbsR = 2.09});
powerValues.Add(new PowerValues(){power=6, powerR=0.003, lightbulbs = 3, lightbulbsR = 2.016});
Console.WriteLine("Power matching criteria . . . ");
DoSomething(powerValues, (e) => e.powerR, 0.003);
Console.WriteLine("Lightbulbs matching criteria . . . ");
DoSomething(powerValues, (e) => e.lightbulbs, 3);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
Extract the code your using twice into one method.
Create an enum for the values you want (e.g. PowerR, OtherField)
Add the enum as a parameter to your method
Add a switch statement in your method to the places where the code changes

How do I create an IComparer for a Nunit CollectionAssert test?

I wish to create the following test in NUnit for the following scenario: we wish to test the a new calculation method being created yields results similar to that of an old system. An acceptable difference (or rather a redefinition of equality) between all values has been defined as
abs(old_val - new_val) < 0.0001
I know that I can loop through every value from the new list and compare to values from the old list and test the above condition.
How would achieve this using Nunit's CollectionAssert.AreEqual method (or some CollectionAssert method)?
The current answers are outdated. Since NUnit 2.5, there is an overload of CollectionAssert.AreEqual that takes a System.Collections.IComparer.
Here is a minimal implementation:
public class Comparer : System.Collections.IComparer
{
private readonly double _epsilon;
public Comparer(double epsilon)
{
_epsilon = epsilon;
}
public int Compare(object x, object y)
{
var a = (double)x;
var b = (double)y;
double delta = System.Math.Abs(a - b);
if (delta < _epsilon)
{
return 0;
}
return a.CompareTo(b);
}
}
[NUnit.Framework.Test]
public void MyTest()
{
var a = ...
var b = ...
NUnit.Framework.CollectionAssert.AreEqual(a, b, new Comparer(0.0001));
}
Well there is method from the NUnit Framework that allows me to do tolerance checks on collections. Refer to the Equal Constraint. One uses the AsCollection and Within extension methods. On that note though I am not 100% sure regarding the implications of this statement made
If you want to treat the arrays being compared as simple collections,
use the AsCollection modifier, which causes the comparison to be made
element by element, without regard for the rank or dimensions of the
array.
[Test]
//[ExpectedException()]
public void CheckLists_FailsAt0()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result1 = new[] { -0.0004, 0.43520, 1.3454, 345345.0980 };
Assert.That(result1, Is.EqualTo(expected).AsCollection.Within(0.0001), "fail at [0]"); // fail on [0]
}
[Test]
//[ExpectedException()]
public void CheckLists_FailAt1()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result1a = new[] { 0.0001000000 , 0.4348245000 , 1.3450234000 , 345345.0975980000 };
Assert.That(result1a, Is.EqualTo(expected).AsCollection.Within(0.0001), "fail at [1]"); // fail on [3]
}
[Test]
public void CheckLists_AllPass_ForNegativeDiff_of_1over10001()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result2 = new[] { 0.00009900 , 0.43532350 , 1.34552240 , 345345.09809700 };
Assert.That(result2, Is.EqualTo(expected).AsCollection.Within(0.0001)); // pass
}
[Test]
public void CheckLists_StillPass_ForPositiveDiff_of_1over10001()
{
var expected = new[] { 0.0001, 0.4353245, 1.3455234, 345345.098098 };
var result3 = new[] { 0.00010100 , 0.43532550 , 1.34552440 , 345345.09809900 };
Assert.That(result3, Is.EqualTo(expected).AsCollection.Within(0.0001)); // pass
}
NUnit does not define any delegate object or interface to perform custom checks to lists, and determine that a expected result is valid.
But I think that the best and simplest option is writing a small static method that achieve your checks:
private const float MIN_ACCEPT_VALUE = 0.0001f;
public static void IsAcceptableDifference(IList collection, IList oldCollection)
{
if (collection == null)
throw new Exception("Source collection is null");
if (oldCollection == null)
throw new Exception("Old collection is null");
if (collection.Count != oldCollection.Count)
throw new Exception("Different lenghts");
for (int i = 0; i < collection.Count; i++)
{
float newValue = (float)collection[i];
float oldValue = (float)oldCollection[i];
float difference = Math.Abs(oldValue - newValue);
if (difference < MIN_ACCEPT_VALUE)
{
throw new Exception(
string.Format(
"Found a difference of {0} at index {1}",
difference,
i));
}
}
}
You've asked how to achieve your desired test using a CollectionAssert method without looping through the list. I'm sure this is obvious, but looping is exactly what such a method would do...
The short answer to your exact question is that you can't use CollectionAssert methods to do what you want. However, if what you really want is an easy way to compare lists of floating point numbers and assert their equality, then read on.
The method Assert.AreEqual( double expected, double actual, double tolerance ) releases you from the need to write the individual item assertions yourself. Using LINQ, you could do something like this:
double delta = 0.0001;
IEnumerable<double> expectedValues;
IEnumerable<double> actualValues;
// code code code
foreach (var pair in expectedValues.Zip(actualValues, Tuple.Create))
{
Assert.AreEqual(pair.Item1, pair.Item2, delta, "Collections differ.");
}
If you wanted to get fancier, you could pull this out into a method of its own, catch the AssertionException, massage it and rethrow it for a cleaner interface.
If you don't care about which items differ:
var areEqual = expectedValues
.Zip(actualValues, Tuple.Create)
.Select(tup => Math.Abs(tup.Item1 - tup.Item2) < delta)
.All(b => b);
Assert.IsTrue(areEqual, "Collections differ.");

Categories