通常建議在.NET編程中使用不可變結構,因爲使用可變結構會爲簡單錯誤設置一個結構。但是,當我嘗試通過實例化新結構來分配新值時,我在C++中得到C3892錯誤,但C#中的等效代碼沒有問題。這是一個問題,因爲這會阻止我初始化一個不可變結構數組。在C++/CLI中將新值分配給不可變值結構
這個問題很容易通過使用readonly屬性而不是字段來解決,但我想知道爲什麼我不能在C++中使用C++/CLI做同樣的事情。我做錯了什麼,或者這只是C++/CLI中的一個限制(或錯誤)?有什麼方法可以在C++/CLI中使用不可變結構數組,還是必須避免它們?
C++頭(名爲 「AnnoyingCppBug.h」):
using namespace System;
namespace AnnoyingCppBug {
public value struct immutableType
{
const int Value;
immutableType(int value)
: Value(value) {}
};
public value struct immutableWorkaround
{
property int Value
{
int get() { return _value; }
}
immutableWorkaround(int value)
: _value(value) {}
private:
int _value;
};
public value struct mutableType
{
int Value;
mutableType(int value)
: Value(value) {}
};
public value struct Class1 abstract sealed
{
static void Test();
};
}
C++源文件:
,做同樣的,但細建立#include "stdafx.h"
#include "AnnoyingCppBug.h"
namespace AnnoyingCppBug {
void Class1::Test()
{
auto imm1 = immutableType(0);
auto imm2 = immutableWorkaround(0);
auto imm3 = mutableType(0);
imm1 = immutableType(1); // error C3892: 'arr1': you cannot assign to a variable that is const
imm2 = immutableWorkaround(1);
imm3 = mutableType(1);
// The reason this matters is because I need to initialize an array:
auto arr = gcnew array<immutableType>(1);
arr[0] = immutableType(0); // error C3892: 'arr1': you cannot assign to a variable that is const
}
}
C#代碼:
struct immutableType
{
public readonly int Value;
public immutableType(int value)
{
Value = value;
}
}
static void Test()
{
var imm = new immutableType(0);
imm = new immutableType(1);
var arr = new immutableType[1];
arr[0] = new immutableType(1);
}
這不是一個bug,編譯器只是遵循C++規則的auto。使用auto你隱藏_issue_。編譯器可以推斷出該上下文中的第一個聲明是const(注意我寫了const,而不是不可變的),那麼它就是你得到的類型。另一方面在C#中const是一個完全不同的東西... –
@AdrianoRepetti我仍然得到相同的錯誤,如果我明確宣佈一個非const類型的imm1聲明,並且該數組也沒有聲明爲一個常量數組在.NET中不存在const數組的類型) –
'const'並不意味着你認爲它的作用,它是純粹的本地C++關鍵字。 CLR沒有任何支持,C++/CLI編譯器盡其所能地使它在行爲上類似,它在這裏。你正在尋找的是'initonly'關鍵字,它與C#中'readonly'關鍵字的確切等價物。 –