2009-10-13 71 views
2

我想創建一個generic listPointF對象的引用。 (不,我不希望創造PointF對象的泛型列表。)但是,下面的行編譯失敗:C++/CLI:拳擊和通用列表

Generic::List<PointF^> ^pointList; // Generates error C3225 

在另一方面,創造PointF引用數組工作沒有問題如下:

array<PointF^> ^points = gcnew array<PointF^>; 

下面是一個簡單的程序:

using namespace System; 
using namespace System::Drawing; 
namespace Generic = System::Collections::Generic; 

int main(array<System::String ^> ^args) 
{ 

    array<PointF^> ^points = gcnew array<PointF^>{ 
     nullptr, PointF(0.0f, 0.0f), PointF(1.0f, 0.0f), nullptr 
    }; 

    Generic::List<PointF^> ^pointList; 
    Console::WriteLine(L"Hello World"); 
    return 0; 
} 

如何創建的PointF引用泛型列表?換句話說,我該如何創建盒裝PointF的通用列表?

回答

4

它是.Net通用的限制,它只接受CLI complient類型,如值類型或對引用類型的引用。它不需要像ref類型的堆棧語義那樣的C++/CLI特定類型(編譯成確定性的最終化),或者在你的情況下,引用一個裝箱值類型。

陣列是CLI原生的,並沒有此限制。

0

PointF不是一個類,它是一個結構。如果沒有在對象內裝入框架,則無法引用該結構。

無論何時使用它,您都可以擁有Object引用的列表,並取消對PointF的引用,或者封裝PointF值的自定義類的列表。

通過與PointF值之間的隱式轉換,您可以使裝箱和拆箱變得透明。我不知道你怎麼把它寫在C++,但在C#它應該是這樣的:

public class PointFObject { 

    // encapsulated PointF structure 
    private PointF _value; 

    // constructor 
    public PointFObject(PointF value) { 
     _value = value; 
    } 

    // implicit conversion to a PointF value 
    public static implicit operator PointF(PointFObject obj) { 
     return obj._value; 
    } 

    // implicit conversion from a PointF value 
    public static implicit operator PointFObject(PointF value) { 
     return new PointFObject(value); 
    } 

} 

現在你可以創建PointFObject的列表,並訪問他們作爲的PointF值的列表:

List<PointFObject> pointList = new List<PointFObject>(); 
pointList.Add(new PointF(0f, 0f)); 
PointF p = pointList[0]; 
+0

爲什麼它然後該數組編譯沒有問題?在這種情況下,編譯器會自動處理裝箱/拆箱。爲什麼在通用列表的情況下它不起作用? – 2009-10-13 08:33:37

0

儘管類型PointF的存儲位置和PointF^所指的堆對象是不同種類的東西,但它們都由相同的Type對象描述。系統通常根據如何使用類型來決定哪種類型的東西代表Type。如果使用PointF類型來描述存儲位置,則將分配該存儲位置以保存結構。 C++/CLI編譯器可以允許聲明一個PointF^變量,但框架沒有這樣的概念。在C++/CLI代碼中,編譯器可以使用類型爲Object的存儲位置來保存對PointF堆對象的引用,或者可以使用Object[]來保存一堆這樣的引用;如果這樣的位置永遠不會暴露給外部世界並且編譯器從不存儲除PointF引用之外的任何內容,編譯器可以知道任何非空引用的目標可以安全地用作PointF。然而,編譯器不能將這些存儲位置暴露給外部代碼,因爲類型系統不提供指示其他代碼應該限於存儲PointF引用的手段。

0

正如其他人所提到的,泛型只接受符合CLS的類型參數。由於PointF^不符合CLS,因此List<PointF^>無效。array<>通過成爲模板類型而不是泛型類型來避免此問題。

但是,有一個(相當容易)的解決方法:創建一個List<Nullable<PointF>>。您的示例程序然後變爲:

using namespace System; 
using namespace System::Drawing; 
namespace Generic = System::Collections::Generic; 

int main(array<System::String ^> ^args) 
{ 

    array<Nullable<PointF>> ^points = gcnew array<Nullable<PointF>> { 
     Nullable<PointF>(), Nullable<PointF>(PointF(0.0f, 0.0f)), Nullable<PointF>(PointF(1.0f, 0.0f)), Nullable<PointF>() 
    }; 

    Generic::List<Nullable<PointF>> pointList(points); 
    pointList.Add(PointF(2., 0.)); 
    Console::WriteLine(L"Hello World"); 
    return 0; 
}