WPF: Equals(Control.background, SolidColorBrush) constantly false - c#

I have a List<SolidColorBrush> lColorBrushes and want to compare the Background of some Buttons with it's content. The Buttons are saved in List<Button> lClickedButtons.
foreach (var oBtn in lClickedButtons)
{
for (var i = 0; i < lColorBrushes.Count; i++)
{
if (Equals(oBtn.Background, lColorBrushes[i]))
{
//oBtn gets cool stuff
}
}
}
I did the exact same thing earlier and it worked tottaly fine. But for whatever reason (I dont see any difference to earlier circumstances of my Code) now the if condition is constantly false. Also if for example oBtn.Background and lColorBrushes[i] both are #FFFF0000.

The reason for Equals() returning false, is that these are two entirely different references, that just happen to have the same Color property.
If you want to compare the two SolidColorBrushes, I suggest you use the IEqualityComparer interface, as such: (source).
public class SolidColorBrushComparer : IEqualityComparer<SolidColorBrush>
{
public bool Equals(SolidColorBrush x, SolidColorBrush y)
{
// If you do not care about opacity, disregard it.
return x.Color == y.Color &&
x.Opacity == y.Opacity;
}
public int GetHashCode(SolidColorBrush obj)
{
return new { C = obj.Color, O = obj.Opacity }.GetHashCode();
}
}
Then, you can use it inside your loop as follows:
foreach (var oBtn in lClickedButtons)
{
for (var i = 0; i < lColorBrushes.Count; i++)
{
if (new SoldiColorBrushComparer().Equals(oBtn.Background, lColorBrushes[i]))
{
//oBtn gets cool stuff
}
}
}

Related

Saving state of multiple checkboxes using lists

I am making application that stores data that users input through form. Since i have quite a few checkboxes and form stretches on multiple pages. I want to save state of these checkboxes so when i go to next page and come back, previously checked checkboxes should be checkedagain.
I am trying to accomplish this by using List<CheckBox> and bool[]. But it just doesnt work for some reason. I dont know what i am missing.
public void Ucitavanje34(bool[] Lista,List<CheckBox> check )
{
foreach (CheckBox ajtem in check)
{
int i = 0;
if (ajtem.Checked==true)
{
Lista[i] = true;
++i;
}
else
{
Lista[i]= false;
++i;
}
}
MessageBox.Show(string.Join(Environment.NewLine,Checkboxstrana3,boolarray ));
}
public void Ucitavanje43(bool[] Lista, List<CheckBox> check)
{
foreach (bool ajtem in Lista)
{
int i = 0;
if (ajtem == true)
{
check[i].Checked = true;
++i;
}
else
{
check[i].Checked = false;
++i;
}
}
MessageBox.Show(string.Join(Environment.NewLine,Stanje));
}
I know i can do this manually(1by1) but it is to cumbersome.
The output i get is just silly and i dont know what i am doing wrong .
You're resetting i to zero for each check box. It would probably be better to use a single for loop and use i for the index on both the List and the bool[].
The other answers already pointed out your problem, I just wanted to provied a different approach because your task is a good example where you can benefit from using LINQ.
bool[] Lista = check.Select(x => x.IsChecked).ToArray();
Refer to https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=netframework-4.8 if you're interested in that.
Your problem is in the for loop
you are doing int i=0; inside forloop. This will always fetch the first element from list.
public void Ucitavanje34(bool[] Lista,List<CheckBox> check )
{
int i = 0; //this line
foreach (CheckBox ajtem in check)
{
Lista[i] = ajtem.Checked;
++i;
}
MessageBox.Show(string.Join(Environment.NewLine,Checkboxstrana3,boolarray ));
}
public Dictionary<string, bool> Save(params CheckBox[] check)
{
Dictionary<string, bool> result = new Dictionary<string, bool>();
foreach (CheckBox item in check)
result.Add(item.Name, item.Checked);
return result;
}
public void Apply(Dictionary<string, bool> savedResults)
{
foreach (var item in savedResults)
{
var check = this.Controls[item.Key];
// var check = this.Controls.Find(item.Key, true).FirstOrDefault(); //easier way to find checkboxes
if(check != null && check.GetType().ToString() == "System.Windows.Forms.CheckBox")
{
((CheckBox)check).Checked = item.Value;
}
}
}
How to call it:
result = Save(checkBox1, checkBox2, checkBox3, checkBox4);
Now, save the result everywhere you want.
How to use it:
Dictionary<string, bool> result = ... // Load from somewhere
Apply(result);

Make using statement usable for multiple disposable objects

I have a bunch of text files in a folder, and all of them should have identical headers. In other words the first 100 lines of all files should be identical. So I wrote a function to check this condition:
private static bool CheckHeaders(string folderPath, int headersCount)
{
var enumerators = Directory.EnumerateFiles(folderPath)
.Select(f => File.ReadLines(f).GetEnumerator())
.ToArray();
//using (enumerators)
//{
for (int i = 0; i < headersCount; i++)
{
foreach (var e in enumerators)
{
if (!e.MoveNext()) return false;
}
var values = enumerators.Select(e => e.Current);
if (values.Distinct().Count() > 1) return false;
}
return true;
//}
}
The reason I am using enumerators is memory efficiency. Instead of loading all file contents in memory I enumerate the files concurrently line-by-line until a mismatch is found, or all headers have been examined.
My problem is evident by the commented lines of code. I would like to utilize a using block to safely dispose all the enumerators, but unfortunately using (enumerators) doesn't compile. Apparently using can handle only a single disposable object. I know that I can dispose the enumerators manually, by wrapping the whole thing in a try-finally block, and running the disposing logic in a loop inside finally, but is seems awkward. Is there any mechanism I could employ to make the using statement a viable option in this case?
Update
I just realized that my function has a serious flaw. The construction of the enumerators is not robust. A locked file can cause an exception, while some enumerators have already been created. These enumerators will not be disposed. This is something I want to fix. I am thinking about something like this:
var enumerators = Directory.EnumerateFiles(folderPath)
.ToDisposables(f => File.ReadLines(f).GetEnumerator());
The extension method ToDisposables should ensure that in case of an exception no disposables are left undisposed.
You can create a disposable-wrapper over your enumerators:
class DisposableEnumerable : IDisposable
{
private IEnumerable<IDisposable> items;
public event UnhandledExceptionEventHandler DisposalFailed;
public DisposableEnumerable(IEnumerable<IDisposable> items) => this.items = items;
public void Dispose()
{
foreach (var item in items)
{
try
{
item.Dispose();
}
catch (Exception e)
{
var tmp = DisposalFailed;
tmp?.Invoke(this, new UnhandledExceptionEventArgs(e, false));
}
}
}
}
and use it with the lowest impact to your code:
private static bool CheckHeaders(string folderPath, int headersCount)
{
var enumerators = Directory.EnumerateFiles(folderPath)
.Select(f => File.ReadLines(f).GetEnumerator())
.ToArray();
using (var disposable = new DisposableEnumerable(enumerators))
{
for (int i = 0; i < headersCount; i++)
{
foreach (var e in enumerators)
{
if (!e.MoveNext()) return false;
}
var values = enumerators.Select(e => e.Current);
if (values.Distinct().Count() > 1) return false;
}
return true;
}
}
The thing is you have to dispose those objects separately one by one anyway. But it's up to you where to encapsulate that logic. And the code I've suggested has no manual try-finally,)
To the second part of the question. If I get you right this should be sufficient:
static class DisposableHelper
{
public static IEnumerable<TResult> ToDisposable<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource, TResult> selector) where TResult : IDisposable
{
var exceptions = new List<Exception>();
var result = new List<TResult>();
foreach (var i in source)
{
try { result.Add(selector(i)); }
catch (Exception e) { exceptions.Add(e); }
}
if (exceptions.Count == 0)
return result;
foreach (var i in result)
{
try { i.Dispose(); }
catch (Exception e) { exceptions.Add(e); }
}
throw new AggregateException(exceptions);
}
}
Usage:
private static bool CheckHeaders(string folderPath, int headersCount)
{
var enumerators = Directory.EnumerateFiles(folderPath)
.ToDisposable(f => File.ReadLines(f).GetEnumerator())
.ToArray();
using (new DisposableEnumerable(enumerators))
{
for (int i = 0; i < headersCount; i++)
{
foreach (var e in enumerators)
{
if (!e.MoveNext()) return false;
}
var values = enumerators.Select(e => e.Current);
if (values.Distinct().Count() > 1) return false;
}
return true;
}
}
and
try
{
CheckHeaders(folderPath, headersCount);
}
catch(AggregateException e)
{
// Prompt to fix errors and try again
}
I'm going to suggest an approach that uses recursive calls to Zip to allow parallel enumeration of a normal IEnumerable<string> without the need to resort to using IEnumerator<string>.
bool Zipper(IEnumerable<IEnumerable<string>> sources, int take)
{
IEnumerable<string> ZipperImpl(IEnumerable<IEnumerable<string>> ss)
=> (!ss.Skip(1).Any())
? ss.First().Take(take)
: ss.First().Take(take).Zip(
ZipperImpl(ss.Skip(1)),
(x, y) => (x == null || y == null || x != y) ? null : x);
var matching_lines = ZipperImpl(sources).TakeWhile(x => x != null).ToArray();
return matching_lines.Length == take;
}
Now build up your enumerables:
IEnumerable<string>[] enumerables =
Directory
.EnumerateFiles(folderPath)
.Select(f => File.ReadLines(f))
.ToArray();
Now it's simple to call:
bool headers_match = Zipper(enumerables, 100);
Here's a trace of running this code against three files with more than 4 lines:
Ben Petering at 5:28 PM ACST
Ben Petering at 5:28 PM ACST
Ben Petering at 5:28 PM ACST
From a call 2019-05-23, James mentioned he’d like the ability to edit the current shipping price rules (eg in shipping_rules.xml) via the admin.
From a call 2019-05-23, James mentioned he’d like the ability to edit the current shipping price rules (eg in shipping_rules.xml) via the admin.
From a call 2019-05-23, James mentioned he’d like the ability to edit the current shipping price rules (eg in shipping_rules.xml) via the admin.
He also mentioned he’d like to be able to set different shipping price rules for a given time window, e.g. Jan 1 to Jan 30.
He also mentioned he’d like to be able to set different shipping price rules for a given time window, e.g. Jan 1 to Jan 30.
He also mentioned he’d like to be able to set different shipping price rules for a given time window, e.g. Jan 1 to Jan 30.
These storyishes should be considered when choosing the appropriate module to use.
These storyishes should be considered when choosing the appropriate module to use.X
These storyishes should be considered when choosing the appropriate module to use.
Note that the enumerations stop when they encountered a mismatch header in the 4th line on the second file. All enumerations then stopped.
Creating an IDisposable wrapper as #Alex suggested is correct. It needs just a logic to dispose already opened files if some of them is locked and probably some logic for error states. Maybe something like this (error state logic is very simple):
public class HeaderChecker : IDisposable
{
private readonly string _folderPath;
private readonly int _headersCount;
private string _lockedFile;
private readonly List<IEnumerator<string>> _files = new List<IEnumerator<string>>();
public HeaderChecker(string folderPath, int headersCount)
{
_folderPath = folderPath;
_headersCount = headersCount;
}
public string LockedFile => _lockedFile;
public bool CheckFiles()
{
_lockedFile = null;
if (!TryOpenFiles())
{
return false;
}
if (_files.Count == 0)
{
return true; // Not sure what to return here.
}
for (int i = 0; i < _headersCount; i++)
{
if (!_files[0].MoveNext()) return false;
string currentLine = _files[0].Current;
for (int fileIndex = 1; fileIndex < _files.Count; fileIndex++)
{
if (!_files[fileIndex].MoveNext()) return false;
if (_files[fileIndex].Current != currentLine) return false;
}
}
return true;
}
private bool TryOpenFiles()
{
bool result = true;
foreach (string file in Directory.EnumerateFiles(_folderPath))
{
try
{
_files.Add(File.ReadLines(file).GetEnumerator());
}
catch
{
_lockedFile = file;
result = false;
break;
}
}
if (!result)
{
DisposeCore(); // Close already opened files.
}
return result;
}
private void DisposeCore()
{
foreach (var item in _files)
{
try
{
item.Dispose();
}
catch
{
}
}
_files.Clear();
}
public void Dispose()
{
DisposeCore();
}
}
// Usage
using (var checker = new HeaderChecker(folderPath, headersCount))
{
if (!checker.CheckFiles())
{
if (checker.LockedFile is null)
{
// Error while opening files.
}
else
{
// Headers do not match.
}
}
}
I also removed .Select() and .Distinct() when checking the lines. The first just iterates over the enumerators array - the same as foreach above it, so you are enumerating this array twice. Then creates a new list of lines and .Distinct() enumerates over it.

Most efficient way of evaluating independent variable for a similar outcome

I am doing a project using Unity and C# but I don't feel this is necessarily Unity related. I have two separate hands that are represented by 2 instances of a hand class.
public class HandController
{//....class}
HandController LeftHand = new HandController();
HandController RightHand = new HandController();
I am constantly doing twice the work in a lot of areas to affect the hands because each hand needs to be treated independently. So for instance I am using a Leap motion controller and if one of the hands is not detected I want to inform the user of this. So I change the color of the hand in the update method.
Color notDetected = Color.red;
Color detected = new Color(189/255.0f, 165/255.0f, 134/255.0f);
if (!LeftHandTracked)
LeftHand.renderer.material.color = notDetected;
if (!RightHandTracked)
RightHand.renderer.material.color = notDetected;
if (LeftHandTracked)
LeftHand.renderer.material.color = detected;
if (RightHandTracked)
RightHand.renderer.material.color = detected;
Is there a more efficient way of doing this? I hate having duplicate if conditionals sprawled all over my code. I also am tracking fingers, so each finger needs to be recognized and I get an even worse chain of if conditionals
if (TappedFingers[0] && !_keySpamBlock)
LeftHand.SetSide(true, _pointer);
if (TappedFingers[1] && !_keySpamBlock)
LeftHand.SetSide(true, _middle);
if (TappedFingers[2] && !_keySpamBlock)
LeftHand.SetSide(true, _ring);
if (TappedFingers[3] && !_keySpamBlock)
LeftHand.SetSide(true, _pinky);
if (TappedFingers[4] && !_keySpamBlock)
RightHand.SetSide(true, _pointer);
if (TappedFingers[5] && !_keySpamBlock)
RightHand.SetSide(true, _middle);
if (TappedFingers[6] && !_keySpamBlock)
RightHand.SetSide(true, _ring);
if (TappedFingers[7] && !_keySpamBlock)
RightHand.SetSide(true, _pinky);
_pinky and _ middle and etc.. are hash values I pass into SetSide method in the HandController class that allow me to access the animationcontroller booleans I have set in Unity. SetSide() basically just sends the true if a user taps their finger and it plays an animation on the appropriate finger.
EDIT: To Clarify a little more whats going on
I am connecting to an API by inheriting a class and establishing an event listener:
public class AppListener : ErghisListener {
public delegate void onUpdate(Data d);
public event onUpdate Updated;
public override void OnErghisFrame(Data data)
{
Loom.QueueOnMainThread(() => { this.Updated(data); });
}
}
Then I have a MainController where recieve the data object from the API:
public class MainController: MonoBehaviour{
private AppListener _appListener;
private int _pointer;
private int _middle;
private int _ring;
private int _pinky;
void Start()
{
this._appListener = new AppListener();
this._appListener.Updated += callback;
this._pointer = Animator.StringToHash("Pointer");
this._middle = Animator.StringToHash("Middle");
this._ring = Animator.StringToHash("Ring");
this._pinky = Animator.StringToHash("Pinky");
}
public void callback(Data d)
{
// Here is where all my annoying if conditionals were.
bool[] TappedFingers = d.tappedF;
}
Your first code snippet would look much more logical if it was something like this:
class HandController : MonoBehaviour
{
bool m_Tracked;
Color NotDetected { get { return Color.red; } }
Color Detected { get { return new Color(189/255.0f, 165/255.0f, 134/255.0f); } }
public bool Tracked
{
if (m_Tracked == value) return;
m_Tracked = value;
renderer.material.color = value ? Detected : NotDetected;
}
}
// ...
LeftHand.Tracked = LeftHandTracked;
if (TappedFingers.Length != FINGERS*2)
{
Debug.LogError("Unexpected amount of fingers: " + TappedFingers.Length);
return;
}
for(int i = 0; i < FINGERS; i++)
{
LeftHand.SetSide(TappedFingers[i], i);
}
for(int i = FINGERS; i < FINGERS*2; i++)
{
RightHand.SetSide(TappedFingers[i], i-FINGERS);
}
You could simply use else here.
if (LeftHandTracked)
LeftHand.renderer.material.color = detected;
else
LeftHand.renderer.material.color = notDetected;
I would prefer inline conditional.
LeftHand.renderer.material.color = LeftHandTracked ? detected : notDetected;
As for the second example, you can wrap all the statements in a single if block to remove visual noise:
if (!_keySpamBlock)
{
if (TappedFingers[0])
LeftHand.SetSide(true, _pointer);
if (TappedFingers[1])
LeftHand.SetSide(true, _middle);
}
The other option with Linq (which is not more efficient, but so much prettier):
var sides = new[] { _pointer, _middle };
if (!_keySpamBlock)
TappedFingers.Zip(sides, (x, y) => { if (x) { LeftHand.SetSide(true, y); });
I'd say this is clear and looks good enough. I don't see how polymorphism could help here, but you could investigate it yourself.
for the first part:
LeftHand.renderer.material.color = LeftHandTracked ? detected : notDetected;
RightHand.renderer.material.color = RightHandTracked ? detected : notDetected;
second part:
if(!_keySpamBlock)
{
int index=Array.FindLastIndex(TappedFingers.Take(8).ToArray(), i => i);
switch (index)
{
case 0: {LeftHand.SetSide(true, _pointer); break;}
case 1: {LeftHand.SetSide(true, _middle); break;}
//.........
case 7: {RightHand.SetSide(true, _pinky); break;}
}
}

Creating,using and comparing elements within a button collection

I'm making a Tic-tac-toe project, and I'm having some difficulties. I've only gotten a loose grip about collections, so you can see the problem.
Thing is, I created 9 buttons which change their Background image when clicked, and disable themselves. I've managed to make it run for 2 players, but my wish is to create some sort of an AI.
I need a button collection so I can compare their properties, and avoid the usual one-by-one comparison and massive and numerous If statements.
What I actually want is to be able to test whether buttons in the same row or column have the same values (background images). What I've used so far is an array of strings that describes the sign value, but it's entirely detached from the buttons, and it would take a lot of time to type out all that code.
If it cannot be done the way I imagined it, please do tell. I am open to suggestions, and would be most grateful.
Oh, and if you need any code, or further detail, let me know.
You need to separate data (array) and presentation (buttons).
Update
I published a sample console project that compiles and runs.
Its model is separate from presentation so you can take TicTacToe.cs and write a GUI for it.
You don't need strings; booleans are fine for two states.
In fact, there is a third state, which is empty, so you can use a nullable boolean.
So X would correspond to true, O to false, and empty space to null.
I'd create a class that encapsulates a nullable boolean square array:
class TicTacToe {
const int Length = 3;
private bool? [][] _data;
private bool? _winner;
public TicTacToe ()
{
_data = Enumerable
.Range (0, Length)
.Select (_ => new bool? [Length])
.ToArray ();
}
}
Then I'd represent rows, columns and diagonals as vectors:
public bool? GetCell (int row, int column)
{
return _data [row][column];
}
public IEnumerable<bool?> GetRow (int index)
{
return _data [index];
}
IEnumerable<int> GetIndices ()
{
return Enumerable.Range (0, Length);
}
public IEnumerable<bool?> GetColumn (int index)
{
return GetIndices ()
.Select (GetRow)
.Select (row => row.ElementAt (index));
}
public IEnumerable<bool?> GetDiagonal (bool ltr)
{
return GetIndices ()
.Select (i => Tuple.Create (i, ltr ? i : Length - 1 - i))
.Select (pos => GetCell (pos.Item1, pos.Item2));
}
public IEnumerable<IEnumerable<bool?>> GetRows ()
{
return GetIndices ()
.Select (GetRow);
}
public IEnumerable<IEnumerable<bool?>> GetColumns ()
{
return GetIndices ()
.Select (GetColumn);
}
public IEnumerable<IEnumerable<bool?>> GetDiagonals ()
{
return new [] { true, false }
.Select (GetDiagonal);
}
public IEnumerable<IEnumerable<bool?>> GetVectors ()
{
return GetDiagonals ()
.Concat (GetRows ())
.Concat (GetColumns ());
}
Then I'd write a function that takes a vector and says if it's a winning one:
static bool? FindWinner (IEnumerable<bool?> vector)
{
try {
return vector
.Distinct ()
.Single ();
} catch (InvalidOperationException) {
return null;
}
}
static bool? FindWinner (IEnumerable<IEnumerable<bool?>> vectors)
{
return vectors
.Select (FindWinner)
.FirstOrDefault (winner => winner.HasValue);
}
public bool? FindWinner ()
{
return FindWinner (GetVectors ());
}
Now we can call GetWinner to find out if somebody already won.
Then I'd write a method to make a move:
public bool MakeMove (int row, int column, bool move)
{
if (_winner.HasValue)
throw new InvalidOperationException ("The game is already won.");
if (_data [row][column].HasValue)
throw new InvalidOperationException ("This cell is already taken.");
_data [row][column] = move;
_winner = FindWinner ();
return move == _winner;
}
public bool? Winner {
get { return _winner; }
}
This was all inside TicTacToe class.
Your GUI should create it and call its methods.
When a button gets clicked, this is what you may do:
private TicTacToe _game = new TicTacToe ();
private Button [][] _buttons = new Button [][3];
const bool HumanPlayer = true;
const bool AIPlayer = false;
public void HandleButtonClick (object sender, EventArgs e)
{
// Assuming you put a Tuple with row and column in button's Tag property
var position = (Tuple<int, int>) ((Button) sender).Tag;
var row = position.Item1;
var column = position.Item2;
// Sanity check
Debug.Asset (sender == _buttons [row][column]);
bool won = _game.MakeMove (row, column, HumanPlayer);
if (won) {
MessageBox.Show ("You won.");
}
RefreshButtons ();
}
void RefreshButtons ()
{
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
var btn = _buttons [i][j];
var cell = _game.GetCell (i, j);
btn.Enabled = !cell.HasValue;
btn.Text = cell.HasValue
? (cell.Value ? "X" : "O")
: string.Empty;
}
}
}
Your AI should also call MakeMove and do its calculations based on information from calling GetRow, GetColumn and GetDiagonal.
I didn't check the code, it's only a sketch. (But the console project should run just fine.)
What I would use is a game state class that contains the current state of the game. For example:
public class Game
{
// These will have null for unselected, true for circle, false for cross, or something like that
public bool?[][] SquareStates = new bool?[3][3];
// Maybe a property to show a game is in progress
public bool GameInProgress = false;
// Maybe a function to restart game
public void Restart() { ... }
// And maybe a function to check for a winner
public string CheckWinner() { ... }
// Maybe another function to make AI make its next move
// and updates SquareStates.
public void AINextMove(out int row, out int column) { ... }
}
Once you have a class like that, your form would simply contain an intance of Game and then update the array of SquareStates as buttons are pressed and then checks for winner, calls AINextMove, checks for winner again, then updates its own button states with the new SquareStates.

Optimizing "this" type of loop

I'm currently (and have in the past been) using this loop to look through an array of custom classes and make sure that a boolean member value of each class in the array is equal. Is there a better (more efficient, simpler to code perhaps) way to do this?
Since that explanation is pretty bad and for lack of a better way to explain it, I'll simply ask, "Is there a better way to optimize 'this' loop?"
//set to true so the loop runs
boolean AllArentEqual = true;
while (AllArentEqual){
//do some stuff to make stuff equal
///// Check if stuff is equal /////
//set to false to determine later
AllArentEqual = false;
//check if any aren't equal
for (int i = 1; i < anArrayOfClass.length; i++){
if (anArrayOfClass[i - 1].BooleanValue != anArrayOfClass[i].BooleanValue){
//one isn't equal so set the loop to be re-run
AllArentEqual = true;
}
}
} //loop until stuff is equal
An obvious minor improvement is the addition of a break:
for (int i = 1; i < anArrayOfClass.length; i++){
if (anArrayOfClass[i - 1].BooleanValue != anArrayOfClass[i].BooleanValue){
//one isn't equal so set the loop to be re-run
AllArentEqual = true;
break; // We're done in this round
}
}
Once it is established that not all are equal, there's no point in checking further.
I would rework this a bit by extracting a method, and then potentially doing something like:
AttemptMakeEqual(anArrayOfClass);
while (anArrayOfClass.Any(c => c.BooleanValue != anArrayOfClass[0].BooleanValue))
{
AttemptMakeEqual(anArrayOfClass);
}
// Extract out a method to:
void AttemptMakeEqual(YourClass[] values)
{
//do some stuff to make stuff equal
}
If there is a chance you may have "all equal" values, and you don't always need to run the operation first (ie: your new version), you could just do:
while (anArrayOfClass.Any(c => c.BooleanValue != anArrayOfClass[0].BooleanValue))
{
//do some stuff to make stuff equal
}
I'd maybe do something like this:
class Widget
{
public Widget( bool truthiness )
{
this.Truthiness = truthiness ;
}
public bool Truthiness { get ; private set ; }
}
class FooBar
{
private Widget[] Widgets { get ; private set; }
private Widget[] GetSomeWidgets()
{
throw new NotImplementedException() ;
}
public FooBar()
{
Widgets = GetSomeWidgets() ;
}
private void WorkOnWidgets()
{
throw new NotImplementedException() ;
}
public void MakeEqual()
{
bool areEqual ; // zero or one widget and it's not a problem
while ( !(areEqual=CheckIfAllWidgetsEqual()) )
{
WorkOnWidgets() ;
}
return ;
}
public bool CheckIfAllWidgetsEqual()
{
bool value = true ;
if ( Widgets.Length > 1 )
{
Widget first = Widgets[0] ;
Widget firstUnequal = Widgets.Skip(1).FirstOrDefault( x => x.Truthiness != first.Truthiness ) ;
value = firstUnequal != null ;
}
return value ;
}
}

Categories