Upcasting and Downcasting

2018. 10. 24. 07:18 from Language/C#

What is upcasting and Downcasting


Upcasting converts an object of specialized type to a more general type.
Downcasting converts an object from general type to a more specialized type.

specialized type = child class / general type = mother class

이거를 specialized는 석사, general은 대학생 이라고 생각하면 쉽다. 대학생이 석사 수업을 받으면 Upcasting, 석사가 대학생 수업을 받으면 Downcasting이 되는 것이다.

example:

1
2
3
4
5
6
7
8
9
10
testDevice Mother1 = new testDevice();
testDevice Mother2 = new testDevice();
 
testDeviceMPlus Child1 = new testDeviceMPlus();
testDeviceMPlus Child2 = new testDeviceMPlus();
 
Mother1 = Child1; // Upcasting. allowed.
Child2 = Mother2; // Downcasting. Illegal. Discovered at compile time.
Child2 = (testDeviceMPlus)Mother2; // Downcasting. Illegal. Discovered at run time.
Child2 = (testDeviceMPlus)Mother1;  // Downcasting. allowed. Mother1 already refers to a testDeviceMPlus
cs



Actual use

Device배열로 자식 class를 전부 넣어놓는다(Upcasting). 이후에 자식 method를 사용할 일이 있으면 Downcasting을 통해서 사용하면된다.


example:

1
2
3
4
5
6
7
8
9
10
11
12
// device
private Device[] Devices;
private CylinderController Cylinder;
                
private void DeviceInit()
{
    Devices = new Device[(int)DeviceList.Size] {
        new CylinderController() { DeviceName = "Cylinder" }    // upcasting
    };
 
    Cylinder = (CylinderController)Devices[(int)DeviceList.Cylinder];   // downcasting
}
cs

Posted by 나무길 :

Accessibility levels

* public, private, protected, internal this are called by access modifier. Only one access modifier is allowed for a member or type, except when you use the protected internal or private protected combinations(private protected is available since C# 7.2).

public : Access is not restricted.

private : Access is limited to contained type.

protected : Access is to the containing class or type derived from the containing class


* Difference between private and protected : Private type can't access at class or type derived from the containing class. So Private's level of limit is more higher than protected.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class testDevice
{
    private string name = "hi";    
}
 
 
public class testDeviceMobileRobot : testDevice
{
    public void changing(string msg)
    {
        base.name = msg;    // CS0122. 보호수준 때문에 testDevice.name에 접근할 수 없습니다.
    }
}




1
2
3
4
5
6
7
8
9
10
11
12
13
public class testDevice
{
    protected string name = "hi";    
}
 
 
public class testDeviceMobileRobot : testDevice
{
    public void changing(string msg)
    {
        base.name = msg;    // Ok.
    }
}




internal : Access is limited to the current assembly. Internal type or members are accessible only within files in the same assembly, as in this example


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Assembly1.cs  
// Compile with: /target:library  
internal class BaseClass
{
    public static int intM = 0;
}
 
// Assembly1_a.cs  
// Compile with: /reference:Assembly1.dll  
class TestAccess
{
    static void Main()
    {
        BaseClass myBase = new BaseClass();   // CS0122  
    }
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Assembly2.cs  
// Compile with: /target:library  
public class BaseClass
{
    internal static int intM = 0;
}
 
// Assembly2_a.cs  
// Compile with: /reference:Assembly2.dll  
public class TestAccess
{
    static void Main()
    {
        BaseClass myBase = new BaseClass();   // Ok.  
        BaseClass.intM = 444;    // CS0117  
    }
}
cs


Posted by 나무길 :

Task가 무한정 늘어나는 현상

async await를 사용할 때 Main Thread는 await를 만나면 현재 위치에서 탈출하여 async method를 호출하던 위치로 돌아간다. 그리고 새로 생성된 thread가 (앞으로 new Thread라고 부름) await아래 구문을 실행한다.



만약 new Thread가 while(true)같은 무한루프에 빠지게 된다면 Thread는 없어지지 않고 계속 남아있는데 문제는 'Task.Add' 를 사용할 때 Thread가 무한루프 안에서 이 문구를 계속 실행하게 된다면 Task 가 무한정 늘어나게 된다.



만약에 아래 있는 코드를 그대로 시행 시키면 tasks.Add(Task.Run(() => DeviceConnection(obj))); 여기서 생성된 task가 죽지 않고 그대로 남는다. 그러면 아랫줄에 var results = await Task.WhenAll(tasks); 에서 results 변수는 데이터 타입이 bool array 인데 array가 그냥 계속 늘어난다. 결국 foreach (bool isDeviceConnected in results) isAllDeviceConnected &= isDeviceConnected; 이 구문에서 원하는대로 동작하지 않는다. 전체 디바이스를 검색하는 것이 아니라 여태까지 검사했던 모든 디바이스 검사하게 된다. 즉 디바이스 검사 결과를 저장하고 다시 가져다 이전 결과와 현재 결과를 종합해서 검사하고 있는 꼴이다.



해결책은 new Thread가 무한루프에 갇히게 해서는 안된다. 타이머를 쓰든 다른 event를 만들든 해서 CheckConnection method를 호출해야한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private Communication()
{
    Log = Logger.Instance;
    LD = MobileRobotController.Instance;
    MPlus = MPlusController.Instance;
 
    StartCommunication();
}
 
private void StartCommunication()
{
    CheckConnection();
}
 
public bool isCommunicateDone = true;
public bool isAllDeviceConnected = true;   // The result of all object connection
 
// Check each object connection by async await
private async Task CheckConnection()
{
    while (isCommunicateDone)
    {
        List<Task<bool>> tasks = new List<Task<bool>>();
        isAllDeviceConnected = true;
 
 
        // Process checking connection by thread
        foreach (TaskList obj in Enum.GetValues(typeof(TaskList)))
        {
            tasks.Add(Task.Run(() => DeviceConnection(obj)));
        }
 
        // Waiting all thread
        var results = await Task.WhenAll(tasks);
 
        // Check all device connection
        foreach (bool isDeviceConnected in results) isAllDeviceConnected &= isDeviceConnected;
 
        await Task.Delay(10);
    }
}
 
private bool DeviceConnection(TaskList Device)
{
     ...........................
}

cs




'Language > C#' 카테고리의 다른 글

Upcasting and Downcasting  (0) 2018.10.24
public, private, protected, internal keyword  (0) 2018.10.24
Object Oriented Robot Programming  (0) 2018.10.14
'await' keyword  (1) 2018.10.13
C# 'sealeld'  (0) 2018.10.09
Posted by 나무길 :