---
# System prepended metadata

title: C# Overview
tags: [Enum, 陣列, C#, Class]

---

# C# Overview
###### tags: `Class` `Enum` `陣列`, `C#`
>取自 `Jia0` 的筆記
>[time=Fri, Jun 7, 2018]

## Object
是call by reference喔!
舉例:
```cpp=
class ObjectTest
{
    public int i = 10;
}
class Program
{
    static void Main(string[] args)
    {
        ObjectTest classRef = new ObjectTest();
        ObjectTest anotherClassRef = classRef;
        Console.WriteLine("Before Changed :{0}", classRef.i);  // 10
        anotherClassRef.i = 20;
        Console.WriteLine("After Changed :{0}", classRef.i);   // 20
    }
}
```

## Enum
[官方參考](https://docs.microsoft.com/zh-tw/dotnet/csharp/language-reference/keywords/enum)
> 有互相轉換效果的自訂型態~
> 也許能用它來做 `dictionary`(?
> [name=徐遠志][color=#d5f970]
```csharp=
public enum ShippingMethod
{
    RegularAirMail = 1,
    RegisterAirMail = 2,
    Express = 3
}

var method = ShippingMethod.Express; 
(int) method;	// 3
method;  	// Express

var methodId = 3;
(ShippingMethod) methodId;	// Express
```

## 陣列們
### 1. [ ] 
特定類型、固定長度
```csharp=
//宣告一個陣列並給初始值
string[] arr = new string[] {"a","b"} ;

//宣告一個長度是5的陣列
string[] arr1 = new string[5];
arr1[0] = "lorem";
Console.WriteLine(arr1[0]); //lorem

//數長度
arr.Length; //2
```
### 2. List 
特定類型、任意長度
用法整理>>[連結](https://msdn.microsoft.com/zh-tw/library/6sh2ey19(v=vs.110).aspx)
```csharp=
List<int> numsList = new List<int>() { 5, 61, 2, 7, 4, 13, 20 };
numsList.Add(1);
numsList.AddRange(new int[3] { 5, 6, 15});

Console.WriteLine(numsList.LastIndexOf(5));  // 8
Console.WriteLine(numsList.IndexOf(5));  // 0

numsList.Remove(61);    // 刪除61，若有重複元素的可以用forLoop
numsList.Clear();       // numsList.Count == 0

//數長度
numList.Count; //11
```

### 3. Array 
任意類型、固定長度
> 也是可以做`dictionary`的`key-value pair`形式呢![color=#d5f970]
```csharp=
Array num = Array.CreateInstance(typeof(String), 3);
num.SetValue("one", 1);
num.SetValue("two", 2);
Console.WriteLine(num.GetValue(2));    //two

//數長度
num.Length; //3
```

很多好用的性質~
```csharp=
var nums = new int[] { 1, 2, 3, 4, 5, 6 };
Array.Clear(nums, 3,3);  // 1 2 3 0 0 0

var copyNums = new int[2];
Array.Copy(nums, copyNums, 2);
foreach(var i in copyNums) Console.WriteLine(i); 
// 1 2

Array.Sort(nums);  // 0 0 0 1 2 3
Array.Reverse(nums);  // 3 2 1 0 0 0 
```

### 4. ArrayList
任意類型、任意長度
[官方參考](https://msdn.microsoft.com/zh-tw/library/system.collections.arraylist(v=vs.110).aspx)
```csharp=
ArrayList list = new ArrayList();

//加東西的方式和 list 一樣
list.Add(0);
list.Add("wendee");

Console.WriteLine(list[0]); //0
Console.WriteLine(list[1]); //wendee

//數長度
list.Count; //2
```


```csharp=
// [[1],[[2],[3]]

// 第1種
ArrayList list = new ArrayList();
list.Add(new int[]{ 1 });
list.Add(new int[,]{ { 2 },{ 3 } });

// 錯誤示範，目前不知道怎麼求
Console.WriteLine(((int[,])((ArrayList)list[1]))[0]);

// 或者是第2種
ArrayList list = new ArrayList();
list.Add(new int[] { 1 });
list.Add(new ArrayList());
((ArrayList)list[1]).Add(2);
((ArrayList)list[1]).Add(3);

Console.WriteLine(((ArrayList)list[1])[0]);  //2

```


## 複製Class
* [官方參考](https://msdn.microsoft.com/zh-tw/library/system.object.memberwiseclone(v=vs.110).aspx)
* [StackOverflow](https://stackoverflow.com/questions/6569486/creating-a-copy-of-an-object-in-c-sharp?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)
```csharp=
namespace ConsoleApp1
{

    class CopyObj
    {
        private string _name;

        public CopyObj(string name)
        {
            this._name = name;
        }

        public string name
        {
            get { return _name; }
            set { _name = value; }
        }
        public String text = "string text in the Object";
        public Int16 Id = 34;
        public object Copy()
        {
            return this.MemberwiseClone();
        }
    }
}
```

```cpp=28
using System;

namespace ConsoleApp1
{
    public class IdInfo
    {
        public int IdNumber;

        public IdInfo(int IdNumber)
        {
            this.IdNumber = IdNumber;
        }
    }

    public class Person
    {
        public int Age;
        public string Name;
        public IdInfo IdInfo;

        public Person ShallowCopy()
        {
            return (Person) this.MemberwiseClone();
        }

        public Person DeepCopy()
        {
            Person other = (Person) this.MemberwiseClone();
            other.IdInfo = new IdInfo(IdInfo.IdNumber);
            return other;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {

            // 起初，只有一個人
            Person p1 = new Person();
            p1.Age = 42;
            p1.Name = "Sam";
            p1.IdInfo = new IdInfo(6565);

            // p2是p1淺層copy，但IdInfo是共用建構子
            Person p2 = p1.ShallowCopy();
            // 當然一開始都一樣
            // p1 instance: Name: Sam, Age: 42, Value: 6565
            // p2 instance: Name: Sam, Age: 42, Value: 6565


            // 後來p1改了他的資料，但只有IdInfo影響到p2
            // 因為p1一開始是使用new IdInfo，所以兩個人的IdInfo指向同一個reference
            p1.Age = 32;
            p1.Name = "Frank";
            p1.IdInfo.IdNumber = 7878;
            // p1 instance: Name: Frank,    Age: 32, Value: 7878
            // p2 instance: Name: Sam,      Age: 42, Value: 7878



            // p3是p1的深層copy
            // 且p3的IdInfo又指向了新的reference
            // 所以p1的改變除了Name, Age甚至是IdInfo完全不影響p3
            Person p3 = p1.DeepCopy();
            p1.Name = "George";
            p1.Age = 39;
            p1.IdInfo.IdNumber = 8641;
            // p1 instance: Name: George,   Age: 39, Value: 8641
            // p3 instance: Name: Frank,    Age: 32, Value: 7878
            
            
            //---------------------------------------------

            var a = new CopyObj("Lance");
            Console.WriteLine(a.name); // Lance

            var b = (CopyObj) a;
            b.name = "Frank named by b";
            Console.WriteLine(a.name); // Frank named by b
            Console.WriteLine(b.name); // Frank named by b

            // c的改變不影響b、a
            var c = (CopyObj) b.Copy();
            c.name = "Andy";
            b.text = "Change from object b";

            // a只影響到b
            a.text = "Change from object a";
            Console.WriteLine(a.name); // Frank named by b
            Console.WriteLine(b.name); // Frank named by b
            Console.WriteLine(c.name); // Andy
            Console.WriteLine(b.text); // Change from object a
            Console.WriteLine(c.text); // Change from object b
        }
    }
}
```

## 惡補區
:::warning
### public / private
* `public` 方案範圍
> can be accessed by any other code in the same `assembly` or another assembly that references it
>[color=transparent]

* `internal` 專案/命名空間範圍
> can be accessed only by code in the same `assembly`.[color=transparent]
* `private` class{ }之中
> can only be accessed by code in the same `class` or `struct`.
> [color=transparent]
* `protected` 不限定同一個命名空間，只要是繼承關係
> 只有在存取是透過 `衍生類別` 類型進行時，才可以存取衍生類別中屬於基底類別的受保護成員。[color=transparent]
* `protected internal` protected + 同一個命名空間類別，不需要繼承關係
> can be accessed by any code in the same assembly, or by any derived class in another assembly.[color=transparent]
:::
:::success
### partial
parital keyword be appended to both `public` and `private` classes. In a partial public class you'd be able to add functionalities to it in multiple source files, in a partial private class you'd be able to add functionalities to it within the same class.
```csharp
public class MyPublicClass
{
    private partial class MyPrivateClass
    {
        int a;
        int b;
    }
    private partial class MyPrivateClass
    {
        int c;
        int d;
    }
}
```
Now the last case , in a partial public class having a partial private class you can add functionality to both in multiple source files.
:::