csharp 数组,列表,词典,Pocos
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 数组,列表,词典,Pocos相关的知识,希望对你有一定的参考价值。
- List: Lists are fast when you need to access an element by index, but searching for an item in a list is slow since it requires a linear search.
- Dictionary: Dictionaries provide fast lookups by key. Keys should be unique and cannot be null.
- HashSet: HashSets are useful when you need fast lookups to see if an element exists in a set or not.
- Stack: Stacks provide LIFO (Last-In-First-Out) behaviour and are useful when you need to provide the user with a way to go back.
- Queue: Queues provide FIFO (First-In-First-Out) behaviour and are useful to process items in the order arrived.
## Lists
Represents a list of objects that can be accessed by an index. <T> here means this is a generic list. If you’re not familiar with generics, check out my YouTube video.
Unlike arrays that are fixed in size, lists can grow in size dynamically. That’s why they’re also called dynamic arrays or vectors. Internally, a list uses an array for storage. If it becomes full, it’ll create a new larger array, and will copy items from the existing array into the new one.
These days, it’s common to use lists instead of arrays, even if you’re working with a fixed set of items.
To create a list:
```C#
var list = new List<int>();
```
If you plan to store large number of objects in a list, you can reduce the cost of reallocations of the internal array by setting an initial size:
```C#
// Creating a list with an initial size
var list = new List<int>(10000);
```
Here are some useful operations with lists:
```C#
// Add an item at the end of the list
list.Add(4);
// Add an item at index 0
list.Insert(4, 0);
// Remove an item from list
list.Remove(1);
// Remove the item at index 0
list.RemoveAt(0);
// Return the item at index 0
var first = list[0];
// Return the index of an item
var index = list.IndexOf(4);
// Check to see if the list contains an item
var contains = list.Contains(4);
// Return the number of items in the list
var count = list.Count;
// Iterate over all objects in a list
foreach (var item in list)
Console.WriteLine(item);
```
Now, let’s see where a list performs well and where it doesn’t.
### Adding/Removing Items at the Beginning or Middle
If you add/remove an item at the beginning or middle of a list, it needs to shift one or more items in its internal array. In the worst case scenario, if you add/remove an item at the very beginning of a list, it needs to shift all existing items. The larger the list, the more costly this operation is going to be. We specify the cost of this operation using Big O notation: O(n), which simply means the cost increases linearly in direct proportion to the size of the input. So, as n grows, the execution time of the algorithm increases in direct proportion to n.
### Adding/Removing Items at the End
Adding/removing an item at the end of a list is a relatively fast operation and does not depend on the size of the list. The existing items do not have to be shifted. This is why the cost of this operation is relatively constant and is not dependent on the number of items in the list. We represent the execution cost of this operation with Big O notation: O(1). So, 1 here means constant.
### Searching for an Item
When using methods that involve searching for an item(e.g. IndexOf, Contains and Find), List performs a linear search. This means, it iterates over all items in its internal array and if it finds a match, it returns it. In the worst case scenario, if this item is at the end of the list, all items in the list need to be scanned before finding the match. Again, this is another example of O(n), where the cost of finding a match is linear and in direct proportion with the number of elements in the list.
### Accessing an Item by an Index
This is what lists are good at. You can use an index to get an item in a list and no matter how big the list is, the cost of accessing an item by index remains relatively constant, hence O(1).
### List in a Nutshell
So, adding/removing items at the end of a list and accessing items by index are fast and efficient operations with O(1). Searching for an item in a list involves a linear search and in the worst case scenario is O(n). If you need to search for items based on some criteria, and not an index (e.g. customer with ID 1234), you may better use a Dictionary.
```C#
// Use collection initializer.
List<string> list1 = new List<string>()
{
"carrot",
"fox",
"explorer"
};
// Use Add method for each element.
List<string> list5 = new List<string>();
list5.Add("carrot");
list5.Add("fox");
list5.Add("explorer");
// Create a list of parts.
var parts = new List<Part>();
// Add parts to the list.
parts.Add(new Part() { PartName = "crank arm", PartId = 1234 });
parts.Add(new Part() { PartName = "chain ring", PartId = 1334 });
/*********************************************/
// remove items
var planIdsToRemove = list.FindAll(x => x.Insureds.Any() == false).Select(x => x.PlanId);
list.RemoveAll(x => planIdsToRemove.Contains(x.PlanId));
/*********************************************/
/* move "Son Durum" policy item to top */
var lastStatusPolicyIx = list.FindLastIndex(x => x.EndorsementNo == -1);
if (lastStatusPolicyIx > 0)
{
var lastStatusPolicy = list.Find(x => x.EndorsementNo == -1);
list.RemoveAt(lastStatusPolicyIx);
list.Insert(0, lastStatusPolicy);
}
/*********************************************/
public class PolicyMessage
{
public class MsgType
{
public MessagingTypesEnum MsgTypeEnum { get; set; }
}
public List<MsgType> MsgTypesList { get; set; }
public class Policy
{
public string Date { get; set; }
public string PolicyNo { get; set; }
public string OldPolicyNo { get; set; }
}
public List<Policy> PoliciesList { get; set; }
}
var policyMessage = new PolicyMessage
{
MsgTypesList = new List<PolicyMessage.MsgType>
{
new PolicyMessage.MsgType {MsgTypeEnum = MessagingTypesEnum.Sms},
new PolicyMessage.MsgType {MsgTypeEnum = MessagingTypesEnum.Email}
},
PoliciesList = new List<PolicyMessage.Policy>
{
new PolicyMessage.Policy
{
Date = oldPolicy.EndDate?.ToString("dd.MM.yyyy") ?? string.Empty,
OldPolicyNo = oldPolicy.PolicyNo.ToString(),
PolicyNo = policy.PolicyNo.ToString()
}
}
};
/*********************************************/
// Anonymous Type Lists
var modelType = typeof(SearchPolicyViewModel);
var modelData = ModelMetadataProviders.Current.GetMetadataForType(null, modelType);
var placeholders = new List<dynamic>();
foreach (var p in modelData.Properties)
{
placeholders.Add(new { PropertyName = p.PropertyName, Placeholder = p.Watermark });
}
// Property name'i "SubeKod" olan list item'dan Placeholder degerini al.
var placeholder = placeholders.First(x => x.PropertyName == "SubeKod").Placeholder;
/* -- OR -- */
var bankBranchList = await _lookUpManager.GetBankBranchList(loginInformation.User.UserName, bankaKod);
var branchListFormatted = bankBranchList.Select(x => new { Id = x.Id, Text = x.DisplayName }).ToList();
/* -- OR -- */
var factors = new List<dynamic> {new {Value = "", Text = ""}};
/*-- OR -- */
var policyInsuredsPreListDynamic = new List<dynamic>();
dynamic dynamicRange = new System.Dynamic.ExpandoObject();
foreach (var policyInsured in policyInsuredsPreList)
{
dynamicRange = policyInsured;
policyInsuredsPreListDynamic.AddRange(dynamicRange);
}
/*********************************************/
// Select columns from lists
var list = (await _store.GetAllPermissions()).Select(r =>
{
return
new
{
id = r.Id.ToString(),
text = r.Title,
parent = !r.ParentId.HasValue ? "#" : r.ParentId.ToString(),
state = new {selected = rolePermissions != null && rolePermissions.Any(rp => rp.Name.Equals(r.RecursiveName))},
a_attr = new {showMenu = r.ShowMenu},
icon = r.ShowMenu ? "" : "../assets/global/img/jstree-key.png"
};
});
/*********************************************/
// Convert list to comma separated string
Console.WriteLine(String.Join(",", new List<uint> { 1, 2, 3, 4, 5 }));
/*********************************************/
// Convert list to queryable
var authList = new List<Auth>();
var q = authList.AsQueryable();
q = q.Where(e => e.RunInNewOffer);
/*********************************************/
// Modify anonymous list
var q = from cf in _productManager.GetAllCapFactors()
join p in _productManager.GetAllProduct()
on cf.ProductId equals p.Id
join f in _productManager.GetAllFactors()
on cf.FactorId equals f.Id
select new
{
cf.Id,
cf.FactorId,
cf.ProductId,
cf.CapUsage
};
var capFactorQList = await q.ToListAsync();
var capFactorList = from cf in capFactorQList
select new
{
cf.Id,
ProductName = cf.ProductId + " - " + cf.ProductName,
FactorName = cf.FactorId + " - " + cf.FactorName,
CapUsageName = EnumHelper<CapUsageTypeEnum>.GetEnumDescription(cf.CapUsage)
};
/*********************************************/
// Get the Count of a List of unknown type
var selectData = from f in await GetAllFactorsList()
join pcf in distinctProductCoverageFactorsList
on f.Id equals pcf.FactorId
select new { f.Id, Text = f.DisplayName };
var selectDatalist = selectData.OrderBy(x => x.Id).ToList();
var selectDataIList = (IList) selectData;
if (selectDataIList != null && selectDataIList.Count > 0)
{
resultDict = new Dictionary<string, object>
{
{ "success", true },
{ "data", selectDatalist }
};
}
/*********************************************/
var ix = datesList.FindIndex(x => startDateInput < x.EndDate && x.StartDate < endDateInput);
return ix >= 0;
/*********************************************/
```
## Dictionary
Dictionary is a collection type that is useful when you need fast lookups by keys. For example, imagine you have a list of customers and as part of a task, you need to quickly look up a customer by their ID (or some other unique identifier, which we call key). With a list, looking up a customer involves a linear search and the cost of this operation, as you learned earlier, is O(n) in the worst case scenario. With a dictionary, however, look ups are very fast with O(1), which means no matter how large the dictionary is, the look up time remans relatively constant.
When storing or retrieving an object in a dictionary, you need to supply a key. The key is a value that uniquely identifies an object and cannot be null. For example, to store a Customer in a Dictionary, you can use CustomerID as the key.
To create a dictionary, first you need to specify the type of keys and values:
```C#
var dictionary = new Dictionary<int, Customer>();
```
Here, our dictionary uses **int** keys and **Customer** values. So, you can store a Customer object in this dictionary as follows:
```C#
dictionary.Add(customer.Id, customer);
```
You can also add objects to a dictionary during initialization:
```C#
var dictionary = new Dictionary<int, Customer>
{
{ customer1.Id, customer1 },
{ customer2.Id, customer2 }
}
```
Later, you can look up customers by their IDs very quickly:
```C#
// Removing an object by its key
dictionary.Remove(1);
// Removing all objects
dictionary.Clear();
```
And here are some other useful methods available in the Dictionary class:
```C#
var count = dictionary.Count;
var containsKey = dictionary.ContainsKey(1);
var containsValue = dictionary.ContainsValue(customer1);
// Iterate over keys
foreach (var key in dictionary.Keys)
Console.WriteLine(dictionary[key]);
// Iterate over values
foreach (var value in dictionary.Values)
Console.WriteLine(value);
// Iterate over dictionary
foreach (var keyValuePair in dictionary)
{
Console.WriteLine(keyValuePair.Key);
Console.WriteLine(keyValuePair.Value);
}
```
So, why are dictionary look ups so fast? A dictionary internally stores objects in an array, but unlike a list, where objects are added at the end of the array (or at the provided index), the index is calculated using a hash function. So, when we store an object in a dictionary, it’ll call the GetHashCode method on the key of the object to calculate the hash. The hash is then adjusted to the size of the array to calculate the index into the array to store the object. Later, when we lookup an object by its key, GetHashCode method is used again to calculate the hash and the index. As you learned earlier, looking up an object by index in an array is a fast operation with O(1). So, unlike lists, looking up an object in a dictionary does not require scanning every object and no matter how large the dictionary is, it’ll remain extremely fast.
So, in the following figure, when we store this object in a dictionary, the GetHashCode method on the key is called. Let’s assume it returns 1234. This hash value is then adjusted based on the size of the internal array. In this figure, length of the internal array is 6. So, the remainder of the division of 1234 by 6 is used to calculate the index (in this case 4). Later, when we need to look up this object, its key used again to calculate the index.
![enter image description here](https://lh3.googleusercontent.com/eXlD9M46RRHpxukppZwYPkawaOjt37U9daLjG-Ec0_mR8XumeQL5p-ct8JgWKj4J78I_PS9_GQnPMQ)
Now, this was a simplified explanation of how hashing works. There is more involved in calculation of hashes, but you don’t really need to know the exact details at this stage (unless for personal interests). All you need to know as a C# developer is that dictionaries are hash-based collections and for that reason lookups are very fast.
```
var resultDict = new Dictionary<string, object>
{
{ "type", "error" },
{ "text", $"{rowIndex} nolu satırdaki kayıtta hata oluştu : {e.Message}" }
};
return Json(resultDict);
/* -- OR -- */
var resultDict = new Dictionary<string, string>();
resultDict.Add("Foo", "TTTDic");
resultDict.Add("Bar", "Scoo");
return Json(resultDict);
/*get value by key */
String foo = Data_Array["Foo"];
/* Does it contain a key? */
if (resultDict.ContainsKey("Bar")) {
}
/* -------------------- */
/* LIST to DICTIONARY */
var lookUpsDictionary = lookUpsList.ToDictionary(li => li.Id, li => li.Description);
/* -------------------- */
/* DICTIONARY to JSON */
var lookUpsJson = JsonConvert.SerializeObject(lookUpsDictionary, Formatting.None);
/* -------------------- */
/* ANONYMOUS TYPES */
dynamic employee = new System.Dynamic.ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
foreach (var property in (IDictionary<string, object>)employee)
{
Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33
```
## HashSet
A HashSet represents a set of unique items, just like a mathematical set (e.g. **{ 1, 2, 3 }**). A set cannot contain duplicates and the order of items is not relevant. So, both **{ 1, 2, 3 }** and **{ 3, 2, 1 }** are equal.
Use a HashSet when you need super fast lookups against a unique list of items. For example, you might be processing a list of orders, and for each order, you need to quickly check the supplier code from a list of valid supplier codes.
A HashSet, similar to a Dictionary, is a hash-based collection, so look ups are very fast with **O(1)**. But unlike a dictionary, it doesn’t store key/value pairs; it only stores values. So, every objects should be unique and this is determined by the value returned from the **GetHashCode** method. So, if you’re going to store custom types in a set, you need to override **GetHashCode **and **Equals **methods in your type.
To create a HashSet:
```C#
var hashSet = new HashSet<int>();
```
You can add/remove objects to a HashSet similar to a List:
```C#
// Initialize the set using object initialization syntax
var hashSet = new HashSet<int>() { 1, 2, 3 };
// Add an object to the set
hashSet.Add(4);
// Remove an object
hashSet.Remove(3);
// Remove all objects
hashSet.Clear();
// Check to see if the set contains an object
var contains = hashSet.Contains(1);
// Return the number of objects in the set
var count = hashSet.Count;
```
HashSet provides many mathematical set operations:
```C#
// Modify the set to include only the objects present in the set and the other set
hashSet.IntersectWith(another);
// Remove all objects in "another" set from "hashSet"
hashSet.ExceptWith(another);
// Modify the set to include all objects included in itself, in "another" set, or both
hashSet.UnionWith(another);
var isSupersetOf = hashSet.IsSupersetOf(another);
var isSubsetOf = hashSet.IsSubsetOf(another);
var equals = hashSet.SetEquals(another);
```
## Stack
Stack is a collection type with Last-In-First-Out (LIFO) behaviour. We often use stacks in scenarios where we need to provide the user with a way to go back. Think of your browser. As you navigate to different web sites, these addresses that you visit are pushed on a stack. Then, when you click the back button, the item on the stack (which represents the current address in the browser) is popped and now we can get the last address you visited from the item on the stack. The undo feature in applications is implemented using a stack as well.
Here is how you can use a Stack in C#:
```C#
var stack = new Stack<string>();
// Push items in a stack
stack.Push("http://www.google.com");
// Check to see if the stack contains a given item
var contains = stack.Contains("http://www.google.com");
// Remove and return the item on the top of the stack
var top = stack.Pop();
// Return the item on the top of the stack without removing it
var top = stack.Peek();
// Get the number of items in stack
var count = stack.Count;
// Remove all items from stack
stack.Clear();
```
Internally, a stack is implemented using an array. Since arrays in C# have a fixed size, as you push items into a stack, it may need to increase its capacity by re-allocating a larger array and copying existing items into the new array. If re-allocation doesn’t need to happen, push is O(1) operation; otherwise, if re-allocation is required, assuming the stack has n elements, all these elements need to be copied to the new array. This leads to runtime complexity of O(n).
**Pop** is an O(1) operation.
**Contains** is a linear search operation with O(n).
## Queue
Queue represents a collection with First-In-First-Out (FIFO) behaviour. We use queues in situations where we need to process items as they arrive.
Three main operations on queue include:
* Enqueue: adding an element to the end of a queue
* Dequeue: removing the element at the front of the queue
* Peek: inspecting the element at the front without removing it.
Here is how you can use a queue:
```C#
var queue = new Queue<string>();
// Add an item to the queue
queue.Enqueue("transaction1");
// Check to see if the queue contains a given item
var contains = queue.Contains("transaction1");
// Remove and return the item on the front of the queue
var front = queue.Dequeue();
// Return the item on the front without removing it
var top = queue.Peek();
// Remove all items from queue
queue.Clear();
// Get the number of items in the queue
var count = queue.Count;
```
## Arrays
```C#
var contaıns = new[] {"UM", "ANN"}.Contains("ANN");
// returns true
/*********************************************/
static void Main()
{
// Create string array with no elements.
var empty1 = new string[] { };
Console.WriteLine(empty1.Length == 0);
// This syntax has the same result.
var empty2 = new string[0];
Console.WriteLine(empty2.Length == 0);
}
/*********************************************/
string[] arr1 = new string[] { "one", "two", "three" };
string[] arr2 = { "one", "two", "three" };
var arr3 = new string[] { "one", "two", "three" };
string[] arr4 = new string[3];
arr4[0] = "one";
arr4[1] = "two";
arr4[2] = "three";
/*********************************************/
static void Main()
{
int[] array = new int[2]; // Create an array.
array[0] = 10;
array[1] = 3021;
Test(array);
Test(null); // No output.
Test(new int[0]); // No output.
}
static void Test(int[] array)
{
if (array != null &&
array.Length > 0)
{
int first = array[0];
Console.WriteLine(first);
}
}
/*********************************************/
static void Main()
{
string[] array = { "red", "blue", "green" };
// Loop with for each and write colors with string interpolation.
foreach (string color in array)
{
System.Console.WriteLine($"Color = {color}");
}
}
/*********************************************/
static void Main()
{
string[] array = { "cat", "dog", "bird", "fish" };
// The dog string is at index 1.
int dogIndex = Array.IndexOf(array, "dog");
Console.WriteLine(dogIndex);
// There is no monkey string in the array.
// ... So IndexOf returns -1.
int monkeyIndex = Array.IndexOf(array, "monkey");
Console.WriteLine(monkeyIndex);
}
/*********************************************/
static void Main()
{
// ... Create 2D array of strings.
string[,] array = new string[,]
{
{"cat", "dog"},
{"bird", "fish"},
};
// ... Print out values.
Console.WriteLine(array[0, 0]);
Console.WriteLine(array[0, 1]);
Console.WriteLine(array[1, 0]);
Console.WriteLine(array[1, 1]);
}
/*********************************************/
static void Main()
{
// A two-dimensional array reference.
int[,] array = new int[2, 2];
array[0, 0] = 1;
Console.WriteLine(array[0, 0]);
// The same reference can hold a different size of array.
array = new int[3, 3];
array[2, 2] = 1;
Console.WriteLine(array[2, 2]);
}
/*********************************************/
static void Main()
{
string[,] codes = new string[,]
{
{"AA", "BB"},
{"CC", "DD"}
};
// Get the upper bound.
// ... Use for-loop over rows.
for (int i = 0; i <= codes.GetUpperBound(0); i++)
{
string s1 = codes[i, 0];
string s2 = codes[i, 1];
Console.WriteLine("{0}, {1}", s1, s2);
}
}
/*********************************************/
static void Main()
{
string[,] words = new string[,]
{
{"ONE", "TWO"},
{"THREE", "FOUR"},
{"FIVE", "SIX"}
};
// Loop based on length.
// ... Assumes each subarray is two elements long.
for (int i = 0; i < words.Length / 2; i++)
{
string s1 = words[i, 0];
string s2 = words[i, 1];
Console.WriteLine("{0}, {1}", s1, s2);
}
}
/*********************************************/
static void Main()
{
int[,] codes = new int[,]
{
{200, 400},
{2000, 4176},
{20000, 40000}
};
// Get all bounds before looping.
int bound0 = codes.GetUpperBound(0);
int bound1 = codes.GetUpperBound(1);
// ... Loop over bounds.
for (int i = 0; i <= bound0; i++)
{
for (int x = 0; x <= bound1; x++)
{
// Display the element at these indexes.
Console.WriteLine(codes[i, x]);
}
Console.WriteLine();
}
}
/*********************************************/
static void PrintFirstElement(bool[,] values)
{
// Display value of first element in first row.
Console.WriteLine(values[0, 0]);
}
static void Main()
{
// Any array size of the right element type can be used.
bool[,] values = new bool[100, 100];
values[0, 0] = true;
PrintFirstElement(values);
}
/*********************************************/
static void Main()
{
// Instantiate a new 2D string array.
string[,] array = new string[2, 2];
array[0, 0] = "top left";
array[0, 1] = "top right";
array[1, 0] = "bottom left";
array[1, 1] = "bottom right";
// Get upper bounds for the array
int bound0 = array.GetUpperBound(0);
int bound1 = array.GetUpperBound(1);
// Use for-loops to iterate over the array elements
for (int variable1 = 0; variable1 <= bound0; variable1++)
{
for (int variable2 = 0; variable2 <= bound1; variable2++)
{
string value = array[variable1, variable2];
Console.WriteLine(value);
}
Console.WriteLine();
}
Console.ReadLine();
}
```
/* pass the generic type as shown below */
Product modelFromDb = await _productManager.GetProductFirstOrDefault(productViewModel.Id);
var modelFromDbDict = ConvertModelClassToDictionary<Product>(modelFromDb);
/* if the model object is null, instantiate a null version of the Product type being passed */
public static Dictionary<string, object> ConvertModelClassToDictionary<T>(object model)
{
if (ReferenceEquals(null, model))
{
model = (T)Activator.CreateInstance(typeof(T), new object[] {});
}
}
/******************************************************************************/
/* setting generic type's property value using reflection */
/* in this example; EmailApiResponse.ServerStatusCode is set to BadRequest */
public class EmailApiResponse {
public HttpStatusCode ServerStatusCode { get; set; }
}
await PostToApiAsJson<EmailApiResponse>();
public static async Task<T> PostToApiAsJson<T>() {
/* create an instance of the EmailApiResponse object */
var returnObj = (T)Activator.CreateInstance(typeof(T), new object[] { });
/* set its ServerStatusCode property value */
var serverStatusCode = typeof(T).GetProperty("ServerStatusCode");/* property name */
if (serverStatusCode != null)
serverStatusCode.SetValue(returnObj, HttpStatusCode.BadRequest, null);
}
var item = new KeyValueItem
{
Foo = "Bee",
Abc = "Scoo"
};
return Json(item);
### Serialize Items to JSON
```
// CONTROLLER
ViewData["NetworkCorporation"] = kurumList.Any()
? new SelectList(kurumList, "MustKod", "KurumIsim", kurumList.First().MustKod)
: MyHelpers.BlankSelectList();
// VIEW
SelectList selectListNetworkCorporation = (SelectList)ViewData["NetworkCorporation"];
var networkCorpsJson = string.Empty;
if (selectListNetworkCorporation != null)
{
var serializer = new JavaScriptSerializer {MaxJsonLength = int.MaxValue};
networkCorpsJson = serializer.Serialize(selectListNetworkCorporation.Items);
}
```
for (int i = 0; i < Model.Insureds.Count; i++)
{
var viewDataDict = new ViewDataDictionary
{
new KeyValuePair<string, object>("Prefix", "Insureds[" + i + "]"),
new KeyValuePair<string, object>("EndorsementType", Model.EndorsementType.ToString()),
new KeyValuePair<string, object>("InsuredId", Model.Insureds[i].Id)
};
@Html.Partial("_Insured", Model.Insureds[i], viewDataDict)
}
以上是关于csharp 数组,列表,词典,Pocos的主要内容,如果未能解决你的问题,请参考以下文章