What happens with properties and arrays in C#? - c#

Okay, I've this classes and main. I'm on VS 2010 Ultimate and .NET 4 Client.
internal class tezt
{
private int[] _numeros = new int[5];
public int[] Numeros
{
get { return _numeros; }
}
}
public class tezt2
{
private int[] _numeros = new int[5];
public int[] Numeros
{
get { return _numeros; }
}
}
class tezt3
{
private int[] _numeros = new int[5];
public int[] Numeros
{
get { return _numeros; }
}
}
internal static class Program
{
private static void Main()
{
var arrNums = new tezt();
var arrNums2 = new tezt2();
var arrNums3 = new tezt3();
Console.WriteLine(arrNums.Numeros[0]);
arrNums.Numeros[0] = 5;
Console.WriteLine(arrNums.Numeros[0]);
Console.WriteLine(arrNums2.Numeros[0]);
arrNums2.Numeros[0] = 6;
Console.WriteLine(arrNums2.Numeros[0]);
Console.WriteLine(arrNums3.Numeros[0]);
arrNums3.Numeros[0] = 7;
Console.WriteLine(arrNums3.Numeros[0]);
Console.ReadKey(true);
}
}
What's happening with these lines:
arrNums.Numeros[0] = 5;
arrNums2.Numeros[0] = 6;
arrNums3.Numeros[0] = 7;
Isn't supposed that because the classes from which those objects are derived from haven't a set parameter, those asignations must not be allowed?
What can be done to avoid that, to restrict that, thad doing thiks like arrNums.Numeros[0] = 5; throws a error?

You're not setting the Numeros property, you are modifying an element at an index inside that property. You are only using the getter for that property.
The assignment that isn't allowed is assigning a new value to that object's property:
arrNums.Numeros = new int[5]; // will not compile.
You could make the getter return an IEnumerable<int> to protect it:
class tezt3
{
private int[] _numeros = new int[5];
public IEnumerable<int> Numeros
{
get { return _numeros; }
}
}
You could also use a ReadOnlyCollection. The pros and cons of using IEnumerable<T> vs ReadOnlyCollection<T> are discussed in depth in this question.

Can I also advice not using arrays on properties. Here is a quote from Framework Design Guidelines
Properties that return arrays can be very misleading. Usually it is
necessary to return a copy of an internal array so that the user
cannot change the internal state. This could lead to inefficient code.
In the following example, the Employees property is accessed twice in
every iteration of the loop. That would be 2n + 1 copies for the
following short code sample:
Company microsoft = GetCompanyData("MSFT");
for (int i = 0; i < microsoft.Employees.Length; i++)
{
if (microsoft.Employees[i].Alias == "kcwalina")
{ ... }
}
Brad Abrams, a annotator of the book, remarks on this pitfall:
Some of the guidelines in this book were debated and agreed on in the
abstract; others were learned in the school of hard knocks. The
guideline on properties that return arrays is in the school of hard
knocks camp. When we were investigating some performance issues in
version 1.0 of the .NET Framework, we noticed that thousands of arrays
were being created and quickly trashed. It turns out that many places
in the Framework itself ran into this pattern. Needless to say, we
fixed those instances and the guidelines. - Brad Abrams

Related

Why are structs slower than classes?

I'm creating a C# console-app. I have some critical paths and thought that creating structs would be faster than creating classes since I would not need garbage collection for structs. In my test however I found the opposite.
In the test below, I create 1000 structs and 1000 classes.
class Program
{
static void Main(string[] args)
{
int iterations = 1000;
Stopwatch sw = new Stopwatch();
sw.Start();
List<Struct22> structures = new List<Struct22>();
for (int i = 0; i < iterations; ++i)
{
structures.Add(new Struct22());
}
sw.Stop();
Console.WriteLine($"Struct creation consumed {sw.ElapsedTicks} ticks");
Stopwatch sw2 = new Stopwatch();
sw2.Start();
List<Class33> classes = new List<Class33>();
for (int i = 0; i < iterations; ++i)
{
classes.Add(new Class33());
}
sw2.Stop();
Console.WriteLine($"Class creation consumed {sw2.ElapsedTicks} ticks");
Console.ReadLine();
}
}
My classe / struct are simple:
class Class33
{
public int Property { get; set; }
public int Field;
public void Method() { }
}
struct Struct22
{
public int Property { get; set; }
public int Field;
public void Method() { }
}
Results (drum roll please...)
Struct creating consuming 3038 ticks
Class creating consuming 404 ticks
So the question is: Why would it take close to 10x the amount of time for a Class than it does for a Struct ?
EDIT. I made the Program "Do something" by just assigning integers to the properties.
static void Main(string[] args)
{
int iterations = 10000000;
Stopwatch sw = new Stopwatch();
sw.Start();
List<Struct22> structures = new List<Struct22>();
for (int i = 0; i < iterations; ++i)
{
Struct22 s = new Struct22()
{
Property = 2,
Field = 3
};
structures.Add(s);
}
sw.Stop();
Console.WriteLine($"Struct creating consuming {sw.ElapsedTicks} ticks");
Stopwatch sw2 = new Stopwatch();
sw2.Start();
List<Class33> classes = new List<Class33>();
for (int i = 0; i < iterations; ++i)
{
Class33 c = new Class33()
{
Property = 2,
Field = 3
};
classes.Add(c);
}
sw2.Stop();
Console.WriteLine($"Class creating consuming {sw2.ElapsedTicks} ticks");
Console.ReadLine();
}
and the result is astounding to me. Classes are still at least 2x but the simple fact of assigning integers had a 20x impact!
Struct creating consuming 903456 ticks
Class creating consuming 4345929 ticks
EDIT: I removed references to Methods so there are no reference types in my Class or Struct:
class Class33
{
public int Property { get; set; }
public int Field;
}
struct Struct22
{
public int Property { get; set; }
public int Field;
}
The performance difference can probably (or at least in part) be explained by a simple example.
For structures.Add(new Struct22()); this is what really happens:
A Struct22 is created and intialized.
The Add method is called, but it receives a copy because the item is a value type.
So calling Add in this case has overhead, incurred by making a new Struct22 and copying all fields and properties into it from the original.
To demonstrate, not focusing on speed but on the fact that copying takes place:
private static void StructDemo()
{
List<Struct22> list = new List<Struct22>();
Struct22 s1 = new Struct22() { Property = 2, Field = 3 }; // #1
list.Add(s1); // This creates copy #2
Struct22 s3 = list[0]; // This creates copy #3
// Change properties:
s1.Property = 777;
// list[0].Property = 888; <-- Compile error, NOT possible
s3.Property = 999;
Console.WriteLine("s1.Property = " + s1.Property);
Console.WriteLine("list[0].Property = " + list[0].Property);
Console.WriteLine("s3.Property = " + s3.Property);
}
This will be the output, proving that both Add() and the use of list[0] caused copies to be made:
s1.Property = 777
list[0].Property = 2
s3.Property = 999
Let this be a reminder that the behaviour of structs can be substantially different compared to objects, and that performance should be just one aspect when deciding what to use.
As commented, deciding on struct vs class has many considerations. I have not seen many people concerned with instantiation as it is usually a very small part of the performance impact based on this descision.
I ran a few tests with your code and found it interesting that as the number of instances increases the struct is faster.
I cant answer your question as it appears that your assertion is not true. Classes do not always instantiate faster than Structs. Everything I have read states the opposite, but your test produces the interesting results you mentioned.
There are tools you can use to really dig in and try to find out why you get the results you do.
10000
Struct creation consumed 2333 ticks
Class creation consumed 1616 ticks
100000
Struct creation consumed 5672 ticks
Class creation consumed 8459 ticks
1000000
Struct creation consumed 73462 ticks
Class creation consumed 221704 ticks
List<T> stores T objects in internal Array.
Each time when the limit of capacity is reached, new double sized internal array is created and all values from old array are copied ...
When you create an empty List and try to populate it 1000 times, internal array recreated and copied about 10 times.
So in Your example classes could create slower, but each time when new array is created, List should copy only references to objects in case of List of Class, and all structure data in case of List of Struct ...
Try to create List with initial capacity initialized, for your code it should be:
new List<Struct22>(1000)
in this case internal array wont be recreated and structure case will work much faster

C#: Immutable class

I have a class which should be immutable in this class i have only get indexer a private set property so why this is not immutable and i can set some field in array as you could see in main class...
class ImmutableMatice
{
public decimal[,] Array { get; private set; } // immutable Property
public ImmutableMatice(decimal[,] array)
{
Array = array;
}
public decimal this[int index1, int index2]
{
get { return Array[index1, index2]; }
}
........
and in main method if i fill this class with data and change the data
static void Main(string[] args)
{
decimal[,] testData = new[,] {{1m, 2m}, {3m, 4m}};
ImmutableMatice matrix = new ImmutableMatice(testData);
Console.WriteLine(matrix[0,0]); // writes 1
testData[0, 0] = 999;
Console.WriteLine(matrix[0,0]); // writes 999 but i thought it should
// write 1 because class should be immutable?
}
}
Is there any way how to make this class immutable?
Ah yes the solution was copy array to new array in constructor like this:
public ImmutableMatice(decimal[,] array)
{
decimal[,] _array = new decimal[array.GetLength(0),array.GetLength(1)];
//var _array = new decimal[,] { };
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
_array[i, j] = array[i, j];
}
}
Array = _array;
}
That is because you are actually changing the data in the ARRAY, rather than the indexer.
static void Main(string[] args)
{
decimal[,] testData = new[,] {{1m, 2m}, {3m, 4m}};
ImmutableMatice matrix = new ImmutableMatice(testData);
Console.WriteLine(matrix[0,0]); // writes 1
testData[0, 0] = 999; // <--- THATS YOUR PROBLEM
Console.WriteLine(matrix[0,0]); // writes 999 but i thought it should
// write 1 because class should be immutable?
}
You can copy the array into your private property in the constructor to avoid this situation.
Note that you indeed cannot write matrix[0,0] = 999; because the indexer has no setter.
Edit
As Chris pointed out (how could I have missed it myself?) - you shouldn't expose the array as a property at all (which means in most cases it doesn't even have to be a property).
Consider the following code instead:
private decimal[,] _myArray; // That's private stuff - can't go wrong there.
public decimal this[int index1, int index2]
{
// If you only want to allow get data from the array, thats all you ever need
get { return Array[index1, index2]; }
}
Your class is immutable, but the objects inside it aren't.
Having public decimal[,] Array { get; private set; } will only guarantee that you cannot set the property Array to a new instance of Array, but it does not prevent you from accessing the existing object and changing its values (which aren't immutable).
You might want to look into the appropriately named ReadOnlyCollection<T> class.
As #Mike pointed out and I looked past the first time: there's a twist to this because you are accessing the value through the testData object and not through matrix. While the original point still stands, it is more exact to say that the problem you have is that you are changing values in the underlying object which has its reference passed around. You're bypassing the ImmutableMatice object alltogether.
The beforementioned solution of using a ReadOnlyCollection<T> still stands: by creating this read-only wrapper around it, you won't be able to change it anymore afterwards. Howver this is only the case when you actually use it the way its intended: through ImmutableMatice and not through the underlying collection which you still have a reference to.
Another solution that solves this problem is to copy the contents of the original array to another one to "disconnect" it from the array your still have a reference to.
In order to illustrate this, consider the following samples. The first one demonstrates how the underlying reference can still be influenced while the second one shows how it can be solved by copying your values to a new array.
void Main()
{
var arr = new[] { 5 };
var coll = new ReadOnlyCollection<int>(arr);
Console.WriteLine (coll[0]); // 5
arr[0] = 1;
Console.WriteLine (coll[0]); // 1
}
void Main()
{
var arr = new[] { 5 };
var arr2 = new int[] { 0 };
Array.Copy(arr, arr2, arr.Length);
var coll = new ReadOnlyCollection<int>(arr2);
Console.WriteLine (coll[0]); // 5
arr[0] = 1;
Console.WriteLine (coll[0]); // 5
}

Pointing to array element

What I'm trying to achieve is say i have an array, i want to be able to modify a specific array element throughout my code, by pointing at it.
for example in C++ i can do this
int main(){
int arr [5]= {1,2,3,4,5};
int *c = &arr[3];
cout << arr[3] <<endl;
*c = 0;
cout << arr[3]<<endl;
}
I did some googling and there seems to be a way to do it through 'unsafe', but i don't really want to go that route.
I guess i could create a variable to store the indexes, but I'm actually dealing with slightly more complexity (a list within a list. so having two index variables seems to add complexity to the code.)
C# has a databinding class, so what I'm currently doing is binding the array element to a textbox (that i have hidden) and modifying that textbox whenever i want to modify the specific array element, but that's also not a good solution (since i have a textbox that's not being used for its intended purpose - a bit misleading).
A C# example of how you would like the use to look would help. If I understand what you're asking, a simple class like this might do it. What you're asking for though, doesn't seem like a very good idea. If you showed the larger scope in which you need this, someone might be able to point out a better design where you didn't need this sort of functionality at all.
public class ListElement<T> {
private IList<T> list;
private int index;
public ListElement(IList<T> list, int index) {
this.list = list;
this.index = index;
}
public T Value {
get {
return list[index];
}
set {
list[index] = value;
}
}
}
a use of this would look like
int[] arr = new int[] {1,2,3,4,5};
ListElement<int> third = new ListElement<int>(arr, 2);
Console.WriteLine(third.Value);
third.Value = 0;
Console.WriteLine(third.Value);
i'm not sure if this fits exactly, but the problem is that these pointers are not possible in c#.
if you have more complicated lists, you can take a look at LinkedList<T>
it provides a performant way if you want to change elements within a list.
I came up with a somewhat solution in C#. Granted this is off the cuff, so it may not work in all situations but I did test it briefly on your situation.
class Wrapper<T>
{
private T[] array;
private T item;
private int index;
public T Item { get { return item; } set { item = value;
array[Index] = value;
} }
public int Index
{
get { return index; }
set
{
index = value;
Item = array[value];
}
}
public Wrapper(T[] arr)
{
array = arr;
}
}
You can then use the class like this:
class Program
{
static void Main(string[] args)
{
int[] i = {1, 2, 3, 4, 5};
i.ToList().ForEach(x => Console.WriteLine(x));
Wrapper<int> w = new Wrapper<int>(i);
w.Index = 2;
w.Item = 5;
i.ToList().ForEach(x => Console.WriteLine(x));
Console.ReadLine();
}
}
This will give the output: 1234512545
It isn't as pretty as the solution in C++ but it will work as you want and provides a more "automatic" version of referencing the array.
I would wrap your arrays in Objects. In C#, stuff that needs pointer manipulation is usually best done with objects.
The advantage is that objects allow clearer naming and access to more complex data structures. You are right, it is not ideal to pass around sets of indices - the ordering and indexing is easily jumbled.. In fact, I think it was people in your position who decided Object-oriented programming would be a good idea!!
So you have class MyArray { }, and can use the 'object reference' as you would a pointer,
plus you can create arrays of MyArray[].

Need help converting this snippet from c to c#

typedef struct {
int e1;
int e2;
int e3;
int e4;
int e5;
} abc;
void Hello(abc * a, int index)
{
int * post = (&(a->e1) + index);
int i;
for(i = 0; i<5; i++)
{
*(post + i) = i;
}
}
The problem I face here is how they able to access the next element in the struct by
*(post + i)
I'm not sure how all these would be done in C# and moreover, I don't want to use unsafe pointers in C#, but something alternate to it.
Thanks!
You should replace the struct with an array of 5 elements.
If you want to, you can wrap the array in a class with five properties.
edit...
When you say 'Wrap,' it generally means to write properties in a class that set or get the value of either a single variable, an array element, or a member of another class whose instance lives inside your class (the usual usage here = 'wrap an object'). Very useful for separating concerns and joining functionality of multiple objects. Technically, all simple properties just 'wrap' their private member variables.
Sample per comment:
class test
{
int[] e = new int[5];
public void Hello(int index)
{
for (int i = 0; i <= 4; i++) {
// will always happen if index != 0
if (i + index > 4) {
MsgBox("Original code would have overwritten memory. .Net will now blow up.");
}
e[i + index] = i;
}
}
public int e1 {
get { return e[0]; }
set { e[0] = value; }
}
public int e2 {
get { return e[1]; }
set { e[1] = value; }
}
//' ETC etc etc with e3-e5 ...
}
The problem with the C code is that if index is greater than 0 it runs off the end of the abc struct, thus overwriting random memory. This is exactly why C#, a safer language, does not allow these sorts of things. The way I'd implement your code in C# would be:
struct abc
{
public int[] e;
}
void Hello(ref abc a, int index)
{
a.e = new int[5];
for (int i = 0; i < 5; ++i)
a.e[index + i] = i;
}
Note that if index > 0, you'll get an out of bounds exception instead of possibly silent memory overwriting as you would in the C snippet.
The thinking behind the C codes is an ill fit for C#. The C code is based on the assumption that the fields of the struct will be placed sequentially in memory in the order defined the fields are defined in.
The above looks like either homework or a contrived example. Without knowing the real intent it's hard to give a concrete example in C#.
other examples here suggest changing the data structure but if you can't/don't want to do that, you can use reflection combined with an array of objects of the struct type to accomplish the same result as above.
void Hello(abc currentObj){
var fields = typeof(abc).GetFields();
for(var i = 0;i<fields.Length;i++){
fields[i].SetValue(currentObj,i);
}
}

Please help me understand anonymous delegates?

I've downloaded the VCSharpSample pack from Microsoft and started reading on Anonymous Delegates. I can more or less understand what the code is doing, but I don't understand the reason behind it. Maybe if you gave me some examples where it would result in cleaner code and easier maintainability then I could wrap my head around it. :)
Can you help?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
delegate decimal CalculateBonus(decimal sales);
class Player
{
public string Name;
public decimal Score;
public decimal Bonus;
public CalculateBonus calculation_algorithm;
}
class Program
{
static decimal calculateStandardBonus(decimal sales)
{
return sales / 10;
}
static void Main(string[] args)
{
decimal multiplier = 2;
CalculateBonus standard_bonus = new CalculateBonus(calculateStandardBonus);
CalculateBonus enhanced_bonus = delegate(decimal sales) { return multiplier * sales / 10; };
Player[] players = new Player[5];
for (int i = 0; i < 5; i++)
{
players[i] = new Player();
}
players[0].Name = "Sergio";
players[0].Score = 240;
players[0].calculation_algorithm = standard_bonus;
players[1].Name = "Sergio";
players[1].Score = 240;
players[1].calculation_algorithm = enhanced_bonus;
players[2].Name = "Caro";
players[2].Score = 89;
players[2].calculation_algorithm = standard_bonus;
players[3].Name = "Andy";
players[3].Score = 38;
players[3].calculation_algorithm = enhanced_bonus;
players[4].Name = "Hugo";
players[4].Score = 600;
players[4].calculation_algorithm = enhanced_bonus;
foreach (Player player in players)
{
PerformCalculationBonus(player);
}
foreach (Player player in players)
{
DisplayPersonalDetails(player);
}
Console.ReadLine();
}
public static void PerformCalculationBonus(Player player)
{
player.Bonus = player.calculation_algorithm(player.Score);
}
public static void DisplayPersonalDetails(Player player)
{
Console.WriteLine(player.Name);
Console.WriteLine(player.Score);
Console.WriteLine(player.Bonus);
Console.WriteLine("---------------");
}
}
}
Anonymous delegates are designed to help you make code more readable by being able to define the behavior of a simple delegate inline in another method. This means that if you're dealing with something that requires a delegate (an event handler, for example), you can define the behavior right in the code rather than creating a dedicated function for it.
In addition, they're the precursor for lambda expressions. Things like LINQ to Objects (any of the methods that operate on IEnumerable<T>) use delegates to perform queries on objects. For example, if you have a collection of strings and you want a query that finds all of them that are five characters long, you can do that with a lambda:
List<string> strings = ...
var query = strings.Where(s => s.Length == 5);
Or you could do it with an anonymous delegate:
var query = strings.Where(delegate(string s) { return s.Length == 5; });
If you didn't have these, your code would look something like this:
var query = strings.Where(IsFiveCharacters);
...
private bool IsFiveCharacters(string input)
{
return input.Length == 5;
}
It's important to realize, though, that lambdas and anonymous delegates are just compiler features. When your code is compiled, it does actually create regular functions like in the last example, but they're hidden and named using characters that are illegal in the language being used. There's a lot of logic that goes around them when doing things like closures (where you access a variable that exists outside of the lambda/anonymous delegate declaration), as well.
The benefit is that you don't have to look somewhere else for the code to do a one-time lookup/change/calculation/whatever. It's a bit annoying to have to add a function (or a whole other class for a function!) you'll only ever use in one place, and then you have to look back later and see what that bit of code was and why it's needed and whether it still is.
With an anonymous delegate, the code is right there in the code that uses it.

Categories

Resources