(原創) 一個C++能跑的泛型,但在C#卻不能跑<已解決> (C/C++) (template) (.NET) (C#) (C++/CLI)
ISO C++
1
/*
2
(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4
Filename : Template_test1.cpp
5
Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
6
Description : template test
7
Release : 06/09/2007 1.0
8
*/
9
#include <iostream>
10
11
using namespace std;
12
13
class Interface1 {
14
public:
15
virtual void func1() = 0;
16
};
17
18
class Interface2 {
19
public:
20
virtual void func1() = 0;
21
};
22
23
class Class1 : public Interface1 {
24
public:
25
void func1() {
26
cout << "Class1's func1" << endl;
27
}
28
};
29
30
class Class2 : public Interface2 {
31
public:
32
void func1() {
33
cout << "Class2's func1" << endl;
34
}
35
};
36
37
class IGeneric {
38
public:
39
virtual void func1() = 0;
40
};
41
42
template<typename T>
43
class Generic1 : public IGeneric {
44
private:
45
T* _aClass;
46
47
public:
48
Generic1(T* aClass) {
49
_aClass = aClass;
50
}
51
52
void func1() {
53
_aClass->func1();
54
}
55
};
56
57
int main() {
58
Interface1* obj1 = new Class1;
59
Interface2* obj2 = new Class2;
60
61
IGeneric* foo = new Generic1<Interface1>(obj1);
62
foo->func1();
63
64
foo = new Generic1<Interface2>(obj2);
65
foo->func1();
66
67
delete obj1;
68
delete obj2;
69
delete foo;
70
}

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

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

執行結果


若使用C++/CLI,也是可以實現
1
/*
2
(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4
Filename : Template_test1.cpp
5
Compiler : Visual C++ 8.0 / C++/CLI
6
Description : template test
7
Release : 06/09/2007 1.0
8
*/
9
#include "stdafx.h"
10
11
using namespace System;
12
13
interface class Interface1 {
14
void func1();
15
};
16
17
interface class Interface2 {
18
void func1();
19
};
20
21
ref class Class1 : public Interface1 {
22
public:
23
virtual void func1() {
24
Console::WriteLine("Class1's func1");
25
}
26
};
27
28
ref class Class2 : public Interface2 {
29
public:
30
virtual void func1() {
31
Console::WriteLine("Class2's func1");
32
}
33
};
34
35
interface class IGeneric {
36
void func1();
37
};
38
39
template<typename T>
40
ref class Generic1 : public IGeneric {
41
private:
42
T^ _aClass;
43
44
public:
45
Generic1(T^ aClass) {
46
_aClass = aClass;
47
}
48
49
virtual void func1() {
50
_aClass->func1();
51
}
52
};
53
54
int main() {
55
Interface1^ obj1 = gcnew Class1;
56
Interface2^ obj2 = gcnew Class2;
57
58
IGeneric^ foo = gcnew Generic1<Interface1>(obj1);
59
foo->func1();
60
61
foo = gcnew Generic1<Interface2>(obj2);
62
foo->func1();
63
}

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

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

執行結果


若用C#,以下代碼無法compile成功
1
using System;
2
3
public interface Interface1 {
4
void func1();
5
}
6
7
public interface Interface2 {
8
void func1();
9
}
10
11
public class Class1 : Interface1 {
12
public void func1() {
13
Console.WriteLine("Class1's func1");
14
}
15
}
16
17
public class Class2 : Interface2 {
18
public void func1() {
19
Console.WriteLine("Class2's func1");
20
}
21
}
22
23
public interface IGeneric {
24
void func1();
25
}
26
27
public class Generic1<T> : IGeneric where T : Interface1, Interface2 {
28
private T _aClass;
29
30
public Generic1(T aClass) {
31
_aClass = aClass;
32
}
33
34
public void func1() {
35
_aClass.func1();
36
}
37
}
38
39
public class main {
40
public static void Main() {
41
Interface1 obj1 = new Class1();
42
Interface2 obj2 = new Class2();
43
44
IGeneric foo = new Generic1<Interface1>(obj1);
45
foo.func1();
46
47
foo = new Generic1<Interface2>(obj2);
48
foo.func1();
49
}
50
}

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

47

48

49

50

C#無法compile成功
錯誤訊息為
Error 1 The call is ambiguous between the following methods or properties: 'Interface1.func1()' and 'Interface2.func1()' D:\__Clare\CSharp\CSharpLab\Class3.cs 43 5 CSharpLab
Error 2 The type 'Interface1' must be convertible to 'Interface2' in order to use it as parameter 'T' in the generic type or method 'Generic1<T>' D:\__Clare\CSharp\CSharpLab\Class3.cs 52 24 CSharpLab
Error 3 The type 'Interface2' must be convertible to 'Interface1' in order to use it as parameter 'T' in the generic type or method 'Generic1<T>' D:\__Clare\CSharp\CSharpLab\Class3.cs 55 15 CSharpLab
Error1我能理解為什麼不能過,不過並非我故意惡搞,因為實務上的確愈到這樣的需求...
Error2和Error3則真的無法理解了..
看來C#的泛型和C++泛型差異頗大...
請各位指點,該怎麼改才好,改了兩天想不出來...。
<06/16/2007>感謝hyifeng多次的指點,C#的Generics寫法如下
1
/*
2
(C) OOMusou 2007 http://oomusou.cnblogs.com
3
4
Filename : Generics_Test1.cs
5
Compiler : Visual Studio 2005 / C# 2.0
6
Description : Generics Test
7
Release : 06/16/2007 1.0
8
*/
9
using System;
10
11
public interface InterfaceBase {
12
void func1();
13
}
14
15
public interface Interface1 : InterfaceBase {
16
}
17
18
public interface Interface2 : InterfaceBase {
19
}
20
21
public class Class1 : Interface1 {
22
public void func1() {
23
Console.WriteLine("Class1's func1");
24
}
25
}
26
27
public class Class2 : Interface2 {
28
public void func1() {
29
Console.WriteLine("Class2's func1");
30
}
31
}
32
33
public interface IGeneric {
34
void func1();
35
}
36
37
public class Generic1<T> : IGeneric where T : InterfaceBase {
38
private T _aClass;
39
40
public Generic1(T aClass) {
41
_aClass = aClass;
42
}
43
44
public void func1() {
45
_aClass.func1();
46
}
47
}
48
49
public class main {
50
public static void Main() {
51
Interface1 obj1 = new Class1();
52
Interface2 obj2 = new Class2();
53
54
IGeneric foo = new Generic1<Interface1>(obj1);
55
foo.func1();
56
57
foo = new Generic1<Interface2>(obj2);
58
foo.func1();
59
}
60
}

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

47

48

49

50

51

52

53

54

55

56

57

58

59

60

之前C#寫法,主要錯誤為
