I have this example code. What I want to do is to make it so that the "Nums" value can only be written to using the "AddNum" method.
namespace ConsoleApplication1
{
public class Person
{
string myName = "N/A";
int myAge = 0;
List<int> _nums = new List<int>();
public List<int> Nums
{
get
{
return _nums;
}
}
public void AddNum(int NumToAdd)
{
_nums.Add(NumToAdd);
}
public string Name { get; set; }
public int Age { get; set; }
}
}
Somehow, I've tried a bunch of things regarding AsReadOnly() and the readonly keyword, but I can't seem to get it to do what I want it to do.
Here is the sample of the code I have to access the property.
Person p1 = new Person();
p1.Nums.Add(25); //access 1
p1.AddNum(37); //access 2
Console.WriteLine("press any key");
Console.ReadLine();
I really want "access 1" to fail, and "access 2" to be the ONLY way that the value can be set. Thanks in advance for the help.
√ DO use ReadOnlyCollection, a subclass of ReadOnlyCollection,
or in rare cases IEnumerable for properties or return values
representing read-only collections.
The quote from this article.
You should have something like this:
List<int> _nums = new List<int>();
public ReadOnlyCollection<int> Nums
{
get
{
return _nums.AsReadOnly();
}
}
In general, collection types make poor properties because even when a collection is wrapped in ReadOnlyCollection, it's inherently unclear what:
IEnumerable<int> nums = myPerson.Nums;
myPerson.AddNum(23);
foreach(int i in nums) // Should the 23 be included!?
...
is supposed to mean. Is the object returned from Nums a snapshot of the numbers that existed when it called, is it a live view?
A cleaner approach is to have a method called something like GetNumsAsArray which returns a new array each time it's called; it may also be helpful in some cases to have a GetNumsAsList variant depending upon what the caller will want to do with the numbers. Some methods only work with arrays, and some only work with lists, so if only one of the above is provided some callers will have to call it and then convert the returned object to the required type.
If performance-sensitive callers will be needing to use this code a lot, it may be helpful to have a more general-purpose method:
int CopyNumsIntoArray(int sourceIndex, int reqCount, ref int[] dest,
int destIndex, CopyCountMode mode);
where CopyCountMode indicates what the code should do the number of items available starting at sourceIndex is greater or less than reqCount; the method should either return the number of items that were available, or throw an exception if it violated the caller's stated expectations. Some callers might start by create and passing in a 10-item array but be prepared to have the method replace it with a bigger array if there are more than ten items to be returned; others might expect that there will be exactly 23 items and be unprepared to handle any other number. Using a parameter to specify the mode will allow one method to service many kinds of callers.
Although many collection authors don't bother including any method that fits the above pattern, such methods can greatly improve efficiency in cases where code wants to work with a significant minority of a collection (e.g. 1,000 items out of a collection of 50,000). In the absence of such methods, code wishing to work with such a range must either ask for a copy of the whole thing (very wasteful) or request thousands of items individually (also wasteful). Allowing the caller to supply the destination array would improve efficiency in the case where the same method makes many queries, especially if the destination array would be large enough to be put on the large object heap.
Related
Within a class I have a property used by a method which I want to remain in the same state after a call to a second method (which might alter that state).
Example: for a property Value I could do something like this:
void MethodOne()
{
...
var tempValue = this.Value;
MethodTwo(); // might modify this.Value
this.Value = tempValue;
...
}
For a single property this isn't a big deal. If I have multiple properties it gets uglier.
I'm looking for a C# solution but would be interested to know if this kind of construct appears in any common language. The sort of syntax I'm after might look something like this:
void MethodOne()
{
...
preserving(this.Value)
{
MethodTwo(); // might modify this.Value
}
...
}
where the preserving keyword could potentially accept multiple properties/fields.
In my specific case it's a recursive method, so the code looks more like:
void MethodOne(object[] args)
{
...
// Do something which might modify this.Value
preserving(this.Value)
{
MethodOne(args);
}
...
}
Is there an accepted pattern / best practice to achieve this?
EDIT
The specific case for which I'm asking is something like this:
For the purposes of sorting lists I have a custom comparison class which implements IComparer. Its Compare method acts on objects which appear in collections (which may therefore be sorted). These collections might be nested, so sorting such a collection might result in the sort function, and therefore Compare(), being called recursively.
The actual comparison function is partially dynamic, which means that it could be set at runtime to something invalid (e.g. non-transitive or non-deterministic). I can't prevent this, so I want to set a limit on the number of comparisons (let's say n-squared, where n is the length of the list being sorted) to protect against cases where an invalid comparison function might result in the sorting algorithm going into an infinite loop.
The Compare method might be called from (e.g.) various LINQ methods such as OrderBy, possibly resulting in lazily evaluated sorts and possibly from code over which I have no control. However, I need to count the number of comparisons in each sort without any 'subsorts' of nested objects corrupting the count (but also counting comparisons in those subsorts).
My code looks something like this:
public int Compare(T x, T y)
{
// this.MaxComparisons is set from outside this code, since this method does not know the length of the list it is sorting.
if (++this.ComparisonCount > this.MaxComparisons)
{
// Error: too many comparisons
}
if (predicate)
{
// Preserve...
tempComparisonCount = this.ComparisonCount;
tempMaxComparisons = this.MaxComparisons;
// ...reset...
this.ComparisonCount = 0;
this.MaxComparisons = ... ; // set as required
var result = this.customComparer.Compare(x.Child, y.Child); // might involve further calls to the above method, which should be counted separately
// ...and restore
this.ComparisonCount = tempComparisonCount;
this.MaxComparisons = tempMaxComparisons;
return result;
}
else
{
return otherComparer.Compare(x, y);
}
}
I hope this makes it clearer why I have asked the question.
private static void Preserving<T>(ref T value, Action act)
{
T old = value;
act();
value = old;
}
then you can do:
Preserving(ref this.Value, MethodTwo);
If you have multiple variables you want to save and restore, you should probably create a Context class containing the state you want to save and then push/pop them from a stack.
I have this scenario in which memory conservation is paramount. I am trying to read in > 1 GB of Peptide sequences into memory and group peptide instances together that share the same sequence. I am storing the Peptide objects in a Hash so I can quickly check for duplication, but found out that you cannot access the objects in the Set, even after knowing that the Set contains that object.
Memory is really important and I don't want to duplicate data if at all possible. (Otherwise I would of designed my data structure as: peptides = Dictionary<string, Peptide> but that would duplicate the string in both the dictionary and Peptide class). Below is the code to show you what I would like to accomplish:
public SomeClass {
// Main Storage of all the Peptide instances, class provided below
private HashSet<Peptide> peptides = new HashSet<Peptide>();
public void SomeMethod(IEnumerable<string> files) {
foreach(string file in files) {
using(PeptideReader reader = new PeptideReader(file)) {
foreach(DataLine line in reader.ReadNextLine()) {
Peptide testPep = new Peptide(line.Sequence);
if(peptides.Contains(testPep)) {
// ** Problem Is Here **
// I want to get the Peptide object that is in HashSet
// so I can add the DataLine to it, I don't want use the
// testPep object (even though they are considered "equal")
peptides[testPep].Add(line); // I know this doesn't work
testPep.Add(line) // THIS IS NO GOOD, since it won't be saved in the HashSet which i use in other methods.
} else {
// The HashSet doesn't contain this peptide, so we can just add it
testPep.Add(line);
peptides.Add(testPep);
}
}
}
}
}
}
public Peptide : IEquatable<Peptide> {
public string Sequence {get;private set;}
private int hCode = 0;
public PsmList PSMs {get;set;}
public Peptide(string sequence) {
Sequence = sequence.Replace('I', 'L');
hCode = Sequence.GetHashCode();
}
public void Add(DataLine data) {
if(PSMs == null) {
PSMs = new PsmList();
}
PSMs.Add(data);
}
public override int GethashCode() {
return hCode;
}
public bool Equals(Peptide other) {
return Sequence.Equals(other.Sequence);
}
}
public PSMlist : List<DataLine> { // and some other stuff that is not important }
Why does HashSet not let me get the object reference that is contained in the HashSet? I know people will try to say that if HashSet.Contains() returns true, your objects are equivalent. They may be equivalent in terms of values, but I need the references to be the same since I am storing additional information in the Peptide class.
The only solution I came up with is Dictionary<Peptide, Peptide> in which both the key and value point to the same reference. But this seems tacky. Is there another data structure to accomplish this?
Basically you could reimplement HashSet<T> yourself, but that's about the only solution I'm aware of. The Dictionary<Peptide, Peptide> or Dictionary<string, Peptide> solution is probably not that inefficient though - if you're only wasting a single reference per entry, I would imagine that would be relatively insignificant.
In fact, if you remove the hCode member from Peptide, that will safe you 4 bytes per object which is the same size as a reference in x86 anyway... there's no point in caching the hash as far as I can tell, as you'll only compute the hash of each object once, at least in the code you've shown.
If you're really desperate for memory, I suspect you could store the sequence considerably more efficiently than as a string. If you give us more information about what the sequence contains, we may be able to make some suggestions there.
I don't know that there's any particularly strong reason why HashSet doesn't permit this, other than that it's a relatively rare requirement - but it's something I've seen requested in Java as well...
Use a Dictionary<string, Peptide>.
Today I've gone through what indexers are, but I am bit confused. Is there really a need for indexers? What are the advantages of using an indexer..... thanks in advance
I guess the simplest answer is to look at how you'd use (say) List<T> otherwise. Would you rather write:
string foo = list[10];
or
string foo = list.Get(10);
Likewise for dictionaries, would you rather use:
map["foo"] = "bar";
or
map.Put("foo", "bar");
?
Just like properties, there's no real need for them compared with just named methods following a convention... but they make code easier to understand, in my view - and that's one of the most important things a feature can do.
Indexers let you get a reference to an object in a collection without having to traverse the whole collections.
Say you have several thousands of objects, and you need the one before last. Instead of iterating over all of the items in the collection, you simply use the index of the object you want.
Indexers do no have to be integers, so you can use a string, for example, (though you can use any object, so long as the collection supports it) as an indexer - this lets you "name" objects in a collection for later retrieval, also quite useful.
I think zedo got closest to the real reason IMHO that they have added this feature. It's for convenience in the same way that we have properties.
The code is easer to type and easier to read, with a simple abstraction to help you understand.
For instance:
string[] array;
string value = array[0];
List<string> list;
string value = list[0]; //Abstracts the list lookup to a call similar to array.
Dictionary<string, int> map;
int value = map["KeyName"]; //Overloaded with string lookup.
Indexers allow you to reference your class in the same way as an array which is useful when creating a collection class, but giving a class array-like behavior can be useful in other situations as well, such as when dealing with a large file or abstracting a set of finite resources.
yes , they are very use of
you can use indexers to get the indexed object.
Taken from MSDN
Indexers are most frequently implemented in types whose primary purpose is to encapsulate an internal collection or array.
Full Story
for some reason, use indexer can let you create meaningful index to store or map your data. then you can get it from other side by the meaningful index.
using System;
/* Here is a simple program. I think this will help you to understand */
namespace Indexers
{
class Demo
{
int[] a = new int[10];
public int Lengths
{
get
{
return a.Length;
}
}
public int this[int index]
{
get
{
return a[index];
}
set
{
a[index] = value;
}
}
}
class Program
{
static void Main(string[] args)
{
Demo d = new Demo(); // Notice here, this is a simple object
//but you can use this like an array
for (int i = 0; i < d.Lengths; i++)
{
d[i] = i;
}
for (int i = 0; i < d.Lengths; i++)
{
Console.WriteLine(d[i]);
}
Console.ReadKey();
}
}
}
/*Output:
0
1
2
3
4
5
6
7
8
9
*/
It seems strange that the language apparently includes no suitable functionality.
I find myself with data that would best be expressed as a multi-dimensional array but it's utterly constant, there is no way anyone could want to change it without also changing the associated code. Faced with such stuff in Delphi the answer is obvious--a constant whose value is the table. However, C# doesn't seem to support anything like this.
Google shows many people griping about this, no good answers.
How do people handle this sort of situation?
(And don't say that constants don't belong in code--the last one I bumped into was all possible permutations of 4 items. Unless the very nature of spacetime changes this is set in stone.)
What happened?? There was an answer that came pretty close, I was asking about a detail and it vanished! Simply declaring an array sort of does the job--the only problem is that the array allocation is going to run every time. The one in front of me contains 96 values--how do I get it to initialize only once? Do I just have to accept scoping it far wider than it should be? (As it stands it's in one 3-line routine that's inside what amounts to an O(n^3) routine.)
ReadOnlyCollection
There's a page in in the C# FAQ about this specific thing.
They suggest using a static readonly array:
static readonly int[,] constIntArray = new int[,] { { 1, 2, 3 }, { 4, 5, 6 }};
However, be aware that this is only sort of constant - you can still reassign individual elements within the array. Also, this has to be specified on the class level since it's a static, but it will work fairly well.
You could use a readonly Hashtable. The only downside is that readonly does not prevent you from changing the value of a particular item in the Hashtable. So it is not truly const.
readonly Hashtable table = new Hashtable(){{1,"One"},{2,"Two"}};
Or an array
public readonly string[,] arry = new string[,]{{"1","2"},{"2","4"}};
Yes, you will need to declare the variable in the appropriate scope so it does not get initialized more than once.
Like they say, just add another layer of indirection. C# doesn't need to provide a specialized data structure as a language primitive, although one does, at times, wish there was a way to make any class immutable, but that's another discussion.
Now you didn't mention if you need to store different things in there. In fact you didn't mention anything other than multi-dimensional and no ability to change the values or the arrays. I don't even know if the access pattern (a single int,int,int indexer) is appropriate.
But in general, for a 3-dimensional jagged array, the following works (but it isn't pretty).
One caveat is the type you construct it with also needs to be immutable, but that's your problem. You can just create your own read-only wrapper.
public static readonly ReadOnlyThreeDimensions<int> MyGlobalThree
= new ReadOnlyThreeDimensions<int>(IntInitializer);
public class ReadOnlyThreeDimensions<T>
{
private T[][][] _arrayOfT;
public ReadOnlyThreeDimensions(Func<T[][][]> initializer)
{
_arrayOfT = initializer();
}
public ReadOnlyThreeDimensions(T[][][] arrayOfT)
{
_arrayOfT = arrayOfT;
}
public T this [int x, int y, int z]
{
get
{
return _arrayOfT[x][y][z];
}
}
}
And then you just need to provide some initializer method, or assign it in a static constructor.
public static int[][][] IntInitializer()
{
return xyz // something that constructs a [][][]
}
Enumerations, surely.
Well, I've taken the approach of the following, it's a little nasty to read but easy to edit.
public struct Something
{
public readonly int Number;
public readonly string Name;
public Something(int num, string name) { this.Number = num; this.Name = name; }
}
public readonly Something[] GlobalCollection = new Something[]
{
new Something(1, "One"),
new Something(2, "Two"),
};
.NET offers a generic list container whose performance is almost identical (see Performance of Arrays vs. Lists question). However they are quite different in initialization.
Arrays are very easy to initialize with a default value, and by definition they already have certain size:
string[] Ar = new string[10];
Which allows one to safely assign random items, say:
Ar[5]="hello";
with list things are more tricky. I can see two ways of doing the same initialization, neither of which is what you would call elegant:
List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);
or
string[] Ar = new string[10];
List<string> L = new List<string>(Ar);
What would be a cleaner way?
EDIT: The answers so far refer to capacity, which is something else than pre-populating a list. For example, on a list just created with a capacity of 10, one cannot do L[2]="somevalue"
EDIT 2: People wonder why I want to use lists this way, as it is not the way they are intended to be used. I can see two reasons:
One could quite convincingly argue that lists are the "next generation" arrays, adding flexibility with almost no penalty. Therefore one should use them by default. I'm pointing out they might not be as easy to initialize.
What I'm currently writing is a base class offering default functionality as part of a bigger framework. In the default functionality I offer, the size of the List is known in advanced and therefore I could have used an array. However, I want to offer any base class the chance to dynamically extend it and therefore I opt for a list.
List<string> L = new List<string> ( new string[10] );
I can't say I need this very often - could you give more details as to why you want this? I'd probably put it as a static method in a helper class:
public static class Lists
{
public static List<T> RepeatedDefault<T>(int count)
{
return Repeated(default(T), count);
}
public static List<T> Repeated<T>(T value, int count)
{
List<T> ret = new List<T>(count);
ret.AddRange(Enumerable.Repeat(value, count));
return ret;
}
}
You could use Enumerable.Repeat(default(T), count).ToList() but that would be inefficient due to buffer resizing.
Note that if T is a reference type, it will store count copies of the reference passed for the value parameter - so they will all refer to the same object. That may or may not be what you want, depending on your use case.
EDIT: As noted in comments, you could make Repeated use a loop to populate the list if you wanted to. That would be slightly faster too. Personally I find the code using Repeat more descriptive, and suspect that in the real world the performance difference would be irrelevant, but your mileage may vary.
Use the constructor which takes an int ("capacity") as an argument:
List<string> = new List<string>(10);
EDIT: I should add that I agree with Frederik. You are using the List in a way that goes against the entire reasoning behind using it in the first place.
EDIT2:
EDIT 2: What I'm currently writing is a base class offering default functionality as part of a bigger framework. In the default functionality I offer, the size of the List is known in advanced and therefore I could have used an array. However, I want to offer any base class the chance to dynamically extend it and therefore I opt for a list.
Why would anyone need to know the size of a List with all null values? If there are no real values in the list, I would expect the length to be 0. Anyhow, the fact that this is cludgy demonstrates that it is going against the intended use of the class.
Create an array with the number of items you want first and then convert the array in to a List.
int[] fakeArray = new int[10];
List<int> list = fakeArray.ToList();
If you want to initialize the list with N elements of some fixed value:
public List<T> InitList<T>(int count, T initValue)
{
return Enumerable.Repeat(initValue, count).ToList();
}
Why are you using a List if you want to initialize it with a fixed value ?
I can understand that -for the sake of performance- you want to give it an initial capacity, but isn't one of the advantages of a list over a regular array that it can grow when needed ?
When you do this:
List<int> = new List<int>(100);
You create a list whose capacity is 100 integers. This means that your List won't need to 'grow' until you add the 101th item.
The underlying array of the list will be initialized with a length of 100.
This is an old question, but I have two solutions. One is fast and dirty reflection; the other is a solution that actually answers the question (set the size not the capacity) while still being performant, which none of the answers here do.
Reflection
This is quick and dirty, and should be pretty obvious what the code does. If you want to speed it up, cache the result of GetField, or create a DynamicMethod to do it:
public static void SetSize<T>(this List<T> l, int newSize) =>
l.GetType().GetField("_size", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(l, newSize);
Obviously a lot of people will be hesitant to put such code into production.
ICollection<T>
This solution is based around the fact that the constructor List(IEnumerable<T> collection) optimizes for ICollection<T> and immediately adjusts the size to the correct amount, without iterating it. It then calls the collections CopyTo to do the copy.
The code for the List<T> constructor is as follows:
public List(IEnumerable<T> collection) {
....
ICollection<T> c = collection as ICollection<T>;
if (collection is ICollection<T> c)
{
int count = c.Count;
if (count == 0)
{
_items = s_emptyArray;
}
else {
_items = new T[count];
c.CopyTo(_items, 0);
_size = count;
}
}
So we can completely optimally pre-initialize the List to the correct size, without any extra copying.
How so? By creating an ICollection<T> object that does nothing other than return a Count. Specifically, we will not implement anything in CopyTo which is the only other function called.
private struct SizeCollection<T> : ICollection<T>
{
public SizeCollection(int size) =>
Count = size;
public void Add(T i){}
public void Clear(){}
public bool Contains(T i)=>true;
public void CopyTo(T[]a, int i){}
public bool Remove(T i)=>true;
public int Count {get;}
public bool IsReadOnly=>true;
public IEnumerator<T> GetEnumerator()=>null;
IEnumerator IEnumerable.GetEnumerator()=>null;
}
public List<T> InitializedList<T>(int size) =>
new List<T>(new SizeCollection<T>(size));
We could in theory do the same thing for AddRange/InsertRange for an existing array, which also accounts for ICollection<T>, but the code there creates a new array for the supposed items, then copies them in. In such case, it would be faster to just empty-loop Add:
public void SetSize<T>(this List<T> l, int size)
{
if(size < l.Count)
l.RemoveRange(size, l.Count - size);
else
for(size -= l.Count; size > 0; size--)
l.Add(default(T));
}
Initializing the contents of a list like that isn't really what lists are for. Lists are designed to hold objects. If you want to map particular numbers to particular objects, consider using a key-value pair structure like a hash table or dictionary instead of a list.
You seem to be emphasizing the need for a positional association with your data, so wouldn't an associative array be more fitting?
Dictionary<int, string> foo = new Dictionary<int, string>();
foo[2] = "string";
The accepted answer (the one with the green check mark) has an issue.
The problem:
var result = Lists.Repeated(new MyType(), sizeOfList);
// each item in the list references the same MyType() object
// if you edit item 1 in the list, you are also editing item 2 in the list
I recommend changing the line above to perform a copy of the object. There are many different articles about that:
String.MemberwiseClone() method called through reflection doesn't work, why?
https://code.msdn.microsoft.com/windowsdesktop/CSDeepCloneObject-8a53311e
If you want to initialize every item in your list with the default constructor, rather than NULL, then add the following method:
public static List<T> RepeatedDefaultInstance<T>(int count)
{
List<T> ret = new List<T>(count);
for (var i = 0; i < count; i++)
{
ret.Add((T)Activator.CreateInstance(typeof(T)));
}
return ret;
}
You can use Linq to cleverly initialize your list with a default value. (Similar to David B's answer.)
var defaultStrings = (new int[10]).Select(x => "my value").ToList();
Go one step farther and initialize each string with distinct values "string 1", "string 2", "string 3", etc:
int x = 1;
var numberedStrings = (new int[10]).Select(x => "string " + x++).ToList();
string [] temp = new string[] {"1","2","3"};
List<string> temp2 = temp.ToList();
After thinking again, I had found the non-reflection answer to the OP question, but Charlieface beat me to it. So I believe that the correct and complete answer is https://stackoverflow.com/a/65766955/4572240
My old answer:
If I understand correctly, you want the List<T> version of new T[size], without the overhead of adding values to it.
If you are not afraid the implementation of List<T> will change dramatically in the future (and in this case I believe the probability is close to 0), you can use reflection:
public static List<T> NewOfSize<T>(int size) {
var list = new List<T>(size);
var sizeField = list.GetType().GetField("_size",BindingFlags.Instance|BindingFlags.NonPublic);
sizeField.SetValue(list, size);
return list;
}
Note that this takes into account the default functionality of the underlying array to prefill with the default value of the item type. All int arrays will have values of 0 and all reference type arrays will have values of null. Also note that for a list of reference types, only the space for the pointer to each item is created.
If you, for some reason, decide on not using reflection, I would have liked to offer an option of AddRange with a generator method, but underneath List<T> just calls Insert a zillion times, which doesn't serve.
I would also like to point out that the Array class has a static method called ResizeArray, if you want to go the other way around and start from Array.
To end, I really hate when I ask a question and everybody points out that it's the wrong question. Maybe it is, and thanks for the info, but I would still like an answer, because you have no idea why I am asking it. That being said, if you want to create a framework that has an optimal use of resources, List<T> is a pretty inefficient class for anything than holding and adding stuff to the end of a collection.
A notice about IList:
MSDN IList Remarks:
"IList implementations fall into three categories: read-only, fixed-size, and variable-size. (...). For the generic version of this interface, see
System.Collections.Generic.IList<T>."
IList<T> does NOT inherits from IList (but List<T> does implement both IList<T> and IList), but is always variable-size.
Since .NET 4.5, we have also IReadOnlyList<T> but AFAIK, there is no fixed-size generic List which would be what you are looking for.
This is a sample I used for my unit test. I created a list of class object. Then I used forloop to add 'X' number of objects that I am expecting from the service.
This way you can add/initialize a List for any given size.
public void TestMethod1()
{
var expected = new List<DotaViewer.Interface.DotaHero>();
for (int i = 0; i < 22; i++)//You add empty initialization here
{
var temp = new DotaViewer.Interface.DotaHero();
expected.Add(temp);
}
var nw = new DotaHeroCsvService();
var items = nw.GetHero();
CollectionAssert.AreEqual(expected,items);
}
Hope I was of help to you guys.
A bit late but first solution you proposed seems far cleaner to me : you dont allocate memory twice.
Even List constrcutor needs to loop through array in order to copy it; it doesn't even know by advance there is only null elements inside.
1.
- allocate N
- loop N
Cost: 1 * allocate(N) + N * loop_iteration
2.
- allocate N
- allocate N + loop ()
Cost : 2 * allocate(N) + N * loop_iteration
However List's allocation an loops might be faster since List is a built-in class, but C# is jit-compiled sooo...