Anonymous classes, temporary data, and collections of anonymous classes - c#

I'm new to anonymous classes, and today I think I ran into the first case where I felt like I could really use them. I'm writing a method that would benefit from storing temporary data inside of a class, and since that class doesn't have any meaning outside of that method, using an anonymous class sure made sense to me (at least at the time it did).
After starting on the coding, it sure seemed like I was going to have to make some concessions. I like to put assign things like calculations to temporary variables, so that during debugging I can verify bits of calculations at a time in logical chunks. Then I want to assign something simpler to the final value. This value would be in the anonymous class.
The problem is that in order to implement my code with anonymous classes concisely, I'd like to use LINQ. The problem here is that I don't think you can do such temporary calculations inside of the statement. or can you?
Here is a contrived example of what I want to do:
namespace AnonymousClassTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
ObservableCollection<RectanglePoints> Points { get; set; }
public class RectanglePoints
{
public Point UL { get; set; }
public Point UR { get; set; }
public Point LL { get; set; }
public Point LR { get; set; }
}
public class DontWantThis
{
public double Width { get; set; }
public double Height { get; set; }
}
private Dictionary<string,string> properties = new Dictionary<string,string>();
private Dictionary<string,double> scaling_factors = new Dictionary<string,double>();
private void Sample()
{
// not possible to do temp variables, so need to have
// longer, more unreadable assignments
var widths_and_heights = from rp in Points
select new
{
Width = (rp.UR.X - rp.UL.X) * scaling_factors[properties["dummy"]],
Height = (rp.LL.Y - rp.UL.Y) * scaling_factors[properties["yummy"]]
};
// or do it in a for loop -- but then you have to use a concrete
// class to deal with the Width and Height storage
List<DontWantThis> other_widths_and_heights = new List<DontWantThis>();
foreach( RectanglePoints rp in Points) {
double base_width = rp.UR.X - rp.UL.X;
double width_scaling_factor = scaling_factors[properties["dummy"]];
double base_height = rp.LL.Y - rp.UL.Y;
double height_scaling_factor = scaling_factors[properties["yummy"]];
other_widths_and_heights.Add( new DontWantThis
{
Width=base_width * width_scaling_factor,
Height=base_height * height_scaling_factor
});
}
// now we want to use the anonymous class, or concrete class, in the same function
foreach( var wah in widths_and_heights)
Console.WriteLine( String.Format( "{0} {1}", wah.Width, wah.Height));
foreach( DontWantThis dwt in other_widths_and_heights)
Console.WriteLine( String.Format( "{0} {1}", dwt.Width, dwt.Height));
}
public Window1()
{
InitializeComponent();
Points = new ObservableCollection<RectanglePoints>();
Random rand = new Random();
for( int i=0; i<10; i++) {
Points.Add( new RectanglePoints { UL=new Point { X=rand.Next(), Y=rand.Next() },
UR=new Point { X=rand.Next(), Y=rand.Next() },
LL=new Point { X=rand.Next(), Y=rand.Next() },
LR=new Point { X=rand.Next(), Y=rand.Next() }
} );
}
Sample();
}
}
}
NOTE: don't try to run this unless you actually add the keys to the Dictionary :)
The creation of the anonymous class in LINQ is awesome, but forces me to do the calculation in one line. Imagine that the calc is way longer than what I've shown. But it is similar in that I will do some Dictionary lookups to get specific values. Debugging could be painful.
The usage of a concrete class gets around this problem of using temporary variables, but then I can't do everything concisely. Yes, I realize that I'm being a little contradictory in saying that I'm looking for conciseness, while asking to be able to save temp variables in my LINQ statement.
I was starting to try to create an anonymous class when looping over Points, but soon realized that I had no way to store it! You can't use a List because that just loses the entire anonymity of the class.
Can anyone suggest a way to achieve what I'm looking for? Or some middle ground? I've read a few other questions here on StackOverflow, but none of them are exactly the same as mine.

Assuming I understand you correctly, the problem is that you have to set all the properties in a single expression. That's definitely the case with anonymous types.
However, you don't have to do it all inline in that expression. I would suggest that if your properties are based on complex expressions, you break those expressions out into helper methods:
var complex = new {
First = ComputeFirstValue(x, y),
Second = ComputeSecondValue(a, b)
...
};
This has the additional potential benefit that you can unit test each of the helper methods individually, if you're a fan of white-box testing (I am).
This isn't going to avoid there being in one big anonymous type initializer expression, but it means the work will be broken up.

Anonymous classes are really intended to simplify stuff dealing with lambdas, not least LINQ. What you're trying to do sounds much more suited to a nested private class. That way, only your class really knows about your temp class. Trying to muck around with anonymous classes seems only to complicate your code.

Related

how to test a setter in c# ?and why?

I am getting started with c#. I am asked to do an assignement that contains writing a unit test for a setter and checking its output. I don't follow the meaning of testing something very trivial that does not contain any logic. here's the example (SetKeywords() is the method to be tested):
public struct Keyword
{
private string keyword;
private KeywordTypes type;
public Keyword(string keyword, KeywordTypes Type =
KeywordTypes.String)
{
this.keyword = keyword;
this.type = Type;
}
public string GetString()
{
return this.keyword;
}
public KeywordTypes WhichType()
{
return this.type;
}
}
public class ShopParser
{
private Keyword[] keywords = new Keyword[0];
public void **SetKeywords**(Keyword[] tags)
{
keywords = tags;
}
}
public Keyword[] GetKeywords()
{
return this.keywords;
}
public static KeywordPair[] ExtractFromTaG(ShopParser parser, string
serializedInput)
{
var findings = new KeywordPair[0];
foreach (var keyword in parser.GetKeywords())
{
var start = serializedInput.IndexOf(keyword.GetStart());
// Check if keyword is in input string, if not continue
with next keyword.
if (start <= -1) continue;
var end = serializedInput.LastIndexOf(keyword.GetEnd());
// Extract the thing between the tags. Tag excluded
start += keyword.GetStart().Length;
var substring = serializedInput.Substring(start, end -
start);
// Add substring to result list
var tmp = new KeywordPair[findings.Length + 1];
var i = 0;
for (; i < findings.Length; ++i)
{
tmp[i] = findings[i];
}
tmp[i] = new KeywordPair(keyword, substring);
findings = tmp;
}
return findings;
}
}
Lack of complex code does not mean there are no design decisions by the author of the class that should be verified and protected by unit tests. I.e. the fact you picked value type for items in the collection makes some behaviors impossible and some trivial - the test are there to clarify that class implements that design decision properly and protects the behavior of the class in case of future modifications.
Unit tests for setters for properties of a collection type (unlike value type int) are actually non trivial because one must verify that contract of the class is defined and properly supported - does setter make a copy of a collection or reference existing one, does it make deep or shallow copy? Testing each of the cases properly is definitely not a trivial task. (Same to lesser extent applies to all reference type properties, but in non-collection cases expectations of behavior are usually more aligned with default).
So what you want to do before writing the test is to decide the behavior of your collection property - does it make copy at the moment of setting or refers to the original live instance. If collection would be of reference type (not the case in the question) you also need to decide if it takes shallow or deep copy (deep copy is unusual).
After you made the decision it is somewhat trivial to write the test to verify. You add following tests:
is the collection exposed via getter has the same items in the same order as one used to call setter (applies to both copy and reference approaches)
use setter with a collection and modify original collection (in case of an array change items in the collection). Verify that the collection exposed by the getter behaves properly (either matches updated one for live reference or stays the same for copied one)
if using collection of non-immutable reference types verify that modifying individual items behave as expected (either reflects modification for non-deep copy or stays the same)
if collection just refers to original one tests may be shortened to just checking for reference equality between the original and value returned by the getter, but doing so will not document expected behavior and limit ability to modify in the future.
One may need additional test to validate that collection returned as result of the getter behaves as designed by the class author - in particular if modification of the resulting collection are reflected in the class' state or not (getter returning shallow/deep copy of the state or just exposing internal state directly as shown in the question).
Please note that it is discouraged to have setters for collection properties - see CA2227: Collection properties should be read only. So code in the question sort of follows the recommendation but better name like "AddKeywords"/"ReplaceKeywords" would clarify behavior rather than general "set".
How to test?
When you call SetKeywords, it should do something. Right now it sets the internal array keywords. So the question you need to ask yourself is how can you be sure it did that? Well you have a GetKeywords method which returns the internal array so we can use that to conduct our tests as below:
[TestClass]
public class ShopParserTests
{
[TestMethod]
public void SetKeyWords__WhenGivenAnArray__MustSetTheInternalArray()
{
// Arrange
var k1 = new Keyword("One", KeywordTypes.String);
var k2 = new Keyword("Two");
var parser = new ShopParser();
var keys = new Keyword[] { k1, k2 };
// Act
parser.SetKeywords(keys);
// Assert
Keyword[] keysReturned = parser.GetKeywords();
Assert.AreEqual(keysReturned[0].GetString(), k1.GetString());
Assert.AreEqual(keysReturned[0].WhichType(), k1.WhichType());
Assert.AreEqual(keysReturned[1].GetString(), k2.GetString());
Assert.AreEqual(keysReturned[1].WhichType(), k2.WhichType());
// More tests
}
}
Some Suggestions
Keep in mind that you may need to write a lot more tests based on your requirements. For example, what if the user does this:
Keyword[] keysReturned = parser.GetKeywords();
keys[0] = new Keyword();
Do you want to allow that?
Also, in C# your classes can be simplified and take advantage of properties. So your Keyword and ShopParser classes be written like this:
public struct Keyword
{
public Keyword(string keyword, KeywordTypes type =
KeywordTypes.String)
{
this.TheKeyword = keyword;
this.KeyType= type;
}
public string TheKeyword { get; private set; }
public KeywordTypes KeyType { get; private set; }
}
public class ShopParser
{
public void SetKeywords(Keyword[] tags)
{
this.KeyWords = tags;
}
public Keyword[] KeyWords { get; private set; }
}

c# Accessing my array inside a class constructor

I'm learning c# and have decided to try and create a functioning chance game, part by part.
I previously created a method that would create a random (yet likely inefficient) array of natural numbers that would not appear more than once.
However, as I try to piece together OOP I realised if I create multiple of these arrays they would be objects, thus should be created by a class.
I have the array created inside a constructor. Yet I cannot access this array from either within the constructor's class or in another class entirely.
class randomArray
{
Random rng = new Random();
protected int amountOfNumbers;
protected int rangeOfNumbers;
public randomArray(int amountOfNumbers, int rangeOfNumbers)
{
this.amountOfNumbers = amountOfNumbers;
this.rangeOfNumbers = rangeOfNumbers;
int[] randomizedArray = new int[amountOfNumbers];
for (int i = 0; i < amountOfNumbers; i++)
{
randomizedArray[i] = rng.Next(1, rangeOfNumbers + 1);
// A test to ensure that each new number generate is not
already part of the array.
for (int j = 0; j < i; j++)
{
while (randomizedArray[i] == randomizedArray[j])
{
randomizedArray[i] = rng.Next(1, rangeOfNumbers + 1);
j = 0;
}
if (randomizedArray[i] != randomizedArray[j])
continue;
}
}
}
public int RangeOfNumbers { get; set; }
public int AmountOfNumbers { get; set; }
I believe I'm failing to either understand the fundamentals of OOP or I am I failing to understand how to utilize classes.
Make your array a member of the actual class, ie property
public class randomArray
{
public int[] RandomizedArray { get; set; }
...
At about this time, you should probably have a read through this
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/class
https://learn.microsoft.com/en-us/dotnet/csharp/properties
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/fields
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constructors
Update
public randomArray(int amountOfNumbers, int rangeOfNumbers)
{
...
RandomizedArray = new int[amountOfNumbers]
// do stuff here
Although the response of #TheGeneral contains the solution and points you towards more documentation for learning about OOP.
I think it is better to give an explanation why your code did not work.
Everything in OOP has a Scope (a certain "area" where it is available) which is, for most of the things in OOP, fenced of by the brackets.
In this instance the scope is based around the constructor, which causes the variables declared in the brackets to only be available inside the brackets. Except when you use an "outside" link like a class variable or property.
public class Example
{
// this is a class variable, this variable is now reachable from outside the class
// definition.
public int aClassVariable;
// this is a class property which because we added the get and set calls generate
// automatically an get and set method (internally)
public bool aClassProperty { get; set; }
public Example()
{
// to set the class variable and property you just give them a value.
aClassVariable = 42;
aClassProperty = true;
// this variable is not available outside the scope of this function,
// this is because you declared the variable inside this function.
// So the variable is only available inside this function as long as this
// function runs (or as it is called "is in scope").
int[] arr = new int[10];
}
}
Also pay attention about the differences between variables and properties, a variable is something every OOP language contains.
But the properties are actually an extension for the variables where the accessing and setting can be modified with a definition of the get and set method.
I would strongly suggest to read the documentation linked from the answer of TheGeneral because it contains far more information about the intricacies of OOP and C# itself.

How to output the members of list items?

I'm a newbie in the C# and .NET at all.
So, I have a collection that contains objects
private List<object> trains = new List<object>();
...
trains.Add(trains[0]);
trains.Add(trains[1]);
trains.Add(trains[2]);
trains.Add(trains[3]);
trains.Add(trains[4]);
And later in my code I must to input all elements of my collection
I'm trying something like that, but it doesn't work
public void Display()
{
...
for (int i = 0; i<trains.Count; i++)
{
Console.WriteLine(trains[i].Number);
Console.WriteLine(trains[i].Destination);
}
}
Help me please, I'm really dont understand how to input it to the console. I read Microsoft documentation about the "List" but :(
You have a list of objects. And object class doesn't have those members (Number and Destination). If you wanna access them either you need to cast your objects to your type or have a list of Train instead of object.
Currently you are storing your objects in a List<object>, Since your class (probably named) Train inherit from Object, you can store its object in object. You need List<Train> and then you can access each member property like:
private List<Train> trains = new List<Train>();
If you can do that for some reason then you have to explicitly cast your object to Train like:
Console.WriteLine(((Train)(trains[i])).Number);
Assuming this
class Train
{
public int Number { get; set; }
public string Destination { get; set; }
}
And that you are doing something like this:
var t1 = new Train();
t1.Number = 1;
t1.Destination = "somewhere";
var t2 = new Train();
t2.Number = 2;
t2.Destination = "somewhereelse";
trains.Add(t1);
trains.Add(t2);
Than you can output using this:
Train train;
foreach(object t in trains)
{
if ((train = t as Train) != null)
{
Console.WriteLine(t.Number);
Console.WriteLine(t.Destination);
}
}
The advantage of using a list of objects is that you can put "anything" there. Not only "Train". But as pointed by #Chris, foreach do not filter, so you have to filter it yourself.
To access the Train object directly, you will need to cast the generic object to a Train object prior to referencing it's exposed properties. This can be done on the fly, it's not necessary to declare the extra variable myTrain here, however for sake of clarity and readability, I generally do it like this.
public void Display()
{
...
for (int i = 0; i<trains.Count; i++)
{
Train myTrain = (Train)trains[i];
Console.WriteLine(myTrain.Number);
Console.WriteLine(myTrain.Destination);
}
}
Others have mentioned and I would agree, I can think of very few situations where you would NEED to use a:
List<object>();
rather than:
List<Train>();
The only thing that jumps out at me would be if you might be storing non Train objects in the same list with Train objects but I cannot think of a good reason to do something like that off the top of my head.

Pattern for reverse-accessible logic changes?

I'm trying to find a design pattern or a best practice, or some other solution for a problem with keeping back versions of business logic within my application. Specifically, I am looking to find a way to determine which logic was used to issue an insurance policy.
I currently have code which looks like this:
public double FixedDeductibleSurchageAmount()
{
double percent = FixedDeductibleSurchargePercent();
double base_premium = CollisionPremium() + TheftPremium();
return (base_premium * percent);
}
I am needing to make a change to the business logic so that this function looks more like:
public double FixedDeductibleSurchageAmount()
{
double percent = FixedDeductibleSurchargePercent();
double base_premium = CollisionPremium() + TheftPremium() + MedicalPremium();
return (base_premium * percent);
}
Where I run into trouble is that existing policies should rate with the previous logic. Is there a design pattern for this? If not, are there any good ways to implement it?
Strategy pattern sounds most applicable. Probably you'd need a factory method or some such that takes in a date to return the appropriate strategy.
You're going to have to use additional data of some form to keep track of precisely what algorithm was used to obtain your data; you'll probably need to change your persistence representation to maintain versioning information about the algorithm used to derive your results.
BTW, you might consider making things like MedicalPremium or TheftPremium a Get-only property, rather than a parameterless function. They fit that paradigm very well.
There are any number of ways you can solve this problem. Some examples:
1) Switch to the new code and add a flag to the user data so that MedicalPremium automatically returns 0 for old users. This is particularly easy if you stored your data in XML; the old data just won't have the flag, and it won't affect your deserialization of the data because XML is flexible.
2) Make the class that contains your function MedicalPremium a base class, and make MedicalPremium virtual. Override it in the derived class, which is your new version. Newer users are the derived class. Old users are created as the base class. For the old users, it always returns 0. Properties can also be virtual just as functions can.
If you have a chance to look at Martin Fowler's Patterns of Enterprise Architecture he talks about individual instance methods, which isn't entirely the same as what you have, but is very similar. It's a great book in any case.
In the meantime, I think you might have to start considering your functions as also being data, and store in your database which function was used. You don't need (but may want) to store the function text, but you do need enough information to determine at run time which method to call. You asked about patterns, and obviously you have a strategy pattern going on here, which you could reference, but I don't know if it will be especially helpful.
Yes there is: the Decorator Pattern. You can use this to extend the behavior of a class with additional wrapper classes. In the example below I combine this with the Template Method Pattern to achieve what I believe you are looking for.
public class BaseSurchargePolicy {
protected abstract double BasePremium { get; }
protected abstract double FixedDeductibleSurchargePercent { get; }
public double FixedDeductibleSurchageAmount{
get
{
return (BasePremium * FixedDeductibleSurchargePercent);
}
}
protected ICollection<string> _ProcessorsUsed;
public IEnumerable<string> ProcessorsUsed
{
get { return ProcessorsUsed; }
}
}
public class OldSurchargePolicy : BaseSurchargePolicy
{
protected double BasePremium
{
_ProcessorsUsed.Add(GetType().Name);
return CollisionPremium + TheftPremium;
}
protected double FixedDeductibleSurchargePercent { get; set; }
public double CollisionPremium { get; set; }
public double TheftPremium { get; set; }
}
public class MedicalSurchargeDecorator: BaseSurchargePolicy
{
private BaseSurchargePolicy _wrapped;
private double _medicalPremium;
public MedicalSurchargeDecorator(BaseSurchargePolicy wrapped, double medicalPremium)
{
_wrapped = wrapped;
_medicalPremium = medicalPremium;
}
protected double BasePremium
{
get
{
_ProcessorsUsed.Add(GetType().Name);
return _wrapped.BasePremium + _medicalPremium;
}
}
protected double FixedDeductibleSurchargePercent {
get { return _wrapped.FixedDeductibleSurchargePercent }
}
}

C# design for an object where some properties are expensive: excuse to make it mutable?

Yes, I know, yet another question about mutable objects. See this for general background and this for the closest analogue to my question. (though it has some C++ specific overtones that don't apply here)
Let's assume that the following pseudo code represents the best interface design. That is, it's the clearest expression of the business semantics (as they stand today) into OO type. Naturally, the UglyData and the things we're tasked to do with it are subject to incremental change.
public class FriendlyWrapper
{
public FriendlyWrapper(UglyDatum u)
{
Foo = u.asdf[0].f[0].o.o;
Bar = u.barbarbar.ToDooDad();
Baz = u.uglyNameForBaz;
// etc
}
public Widget Foo { get; private set; }
public DooDad Bar { get; private set; }
public DooDad Baz { get; private set; }
// etc
public WhizBang Expensive1 { get; private set; }
public WhizBang Expensive2 { get; private set; }
public void Calculate()
{
Expensive1 = Calc(Foo, Bar);
Expensive2 = Calc(Foo, Baz);
}
private WhizBang Calc(Widget a, DooDad b) { /* stuff */ }
public override void ToString()
{
return string.Format("{0}{1}{2}{3}{4}", Foo, Bar, Baz, Expensive1 ?? "", Expensive2 ?? "");
}
}
// Consumer 1 is happy to work with just the basic wrapped properties
public string Summarize()
{
var myStuff = from u in data
where IsWhatIWant(u)
select new FriendlyWrapper(u);
var sb = new StringBuilder();
foreach (var s in myStuff)
{
sb.AppendLine(s.ToString());
}
return sb.ToString();
}
// Consumer 2's job is to take the performance hit up front. His callers might do things
// with expensive properties (eg bind one to a UI element) that should not take noticeable time.
public IEnumerable<FriendlyWrapper> FetchAllData(Predicate<UglyDatum> pred)
{
var myStuff = from u in data
where pred(u)
select new FriendlyWrapper(u);
foreach (var s in myStuff)
{
s.Calculate(); // as written, this doesn't do what you intend...
}
return myStuff;
}
What's the best route here? Options I can see:
Mutable object with an explicit Calculate() method, as above
Mutable object where expensive calculations are done in the getters (and probably cached)
Split into two objects where one inherits (or perhaps composes?) from the other
Some sort of static + locking mechanism, as in the C++ question linked above
I'm leaning toward #2 myself. But every route has potential pitfalls.
If you choose #1 or #2, then how would you implement Consumer2's loop over mutables in a clear, correct manner?
If you choose #1 or #3, how would you handle future situations where you only want to calculate some properties but not others? Willing to create N helper methods / derived classes?
If you choose #4, I think you're crazy, but feel free to explain
In your case, since you're using LINQ, you're only going to constructing these objects in cases where you want the calculation.
If that is your standard usage pattern, I would just put the expensive calculation directly in the constructor. Using lazy initialization is always slower unless you plan to have some cases where you do not calculate. Doing the calculation in the getters will not save anything (at least in this specific case).
As for mutability - mutable objects with reference syntax and identity (ie: classes in C#) are really okay - it's more a problem when you're dealing with mutable value types (ie: structs). There are many, many mutable classes in the .NET BCL - and they don't cause issues. The problem is typically more of one when you start dealing with value types. Mutable value types lead to very unexpected behavior.
In general, I'd turn this question upside down - How and where are you going to use this object? How can you make this object the most performant (if it's been determined to be problematic) without affecting usability? Your 1), 3) and 4) options would all make usability suffer, so I'd avoid them. In this case, doing 2) won't help. I'd just put it in the constructor, so your object's always in a valid state (which is very good for usability and maintainability).

Categories