(原創) 一個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
(C) OOMusou 2007 http://oomusou.cnblogs.com3

4
Filename : Template_test1.cpp5
Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++6
Description : template test7
Release : 06/09/2007 1.08
*/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
}執行結果
Class1's func1
Class2's func1若使用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
(C) OOMusou 2007 http://oomusou.cnblogs.com3

4
Filename : Template_test1.cpp5
Compiler : Visual C++ 8.0 / C++/CLI6
Description : template test7
Release : 06/09/2007 1.08
*/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
}執行結果
Class1's func1
Class2's func1若用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
}
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
}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
(C) OOMusou 2007 http://oomusou.cnblogs.com3

4
Filename : Generics_Test1.cs5
Compiler : Visual Studio 2005 / C# 2.06
Description : Generics Test7
Release : 06/16/2007 1.08
*/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
}之前C#寫法,主要錯誤為
public class Generic1<T> : IGeneric where T : Interface1, Interface2


浙公网安备 33010602011771号