2017-02-23 68 views
0

我在做我的工作時遇到了一個問題,那就是將軟件從AS3移植到.NET/Mono。在AS3的代碼庫,我可以找到很多Object聲明說都是這樣初始化:爲什麼你不能聲明一個字段和屬性具有匿名類型?

private const MAPPING:Object = 
{ 
    ssdungf:'flydung', 
    ssdungt:'flydung', 
    superfutter:'superfeed' 
} 

最好的選擇,我會使用匿名類型像這樣在C#:

var MAPPING = new 
{ 
    ssdungf = "flydung", 
    ssdungt = "flydung", 
    superfutter = "superfeed" 
}; 

的問題是..那麼,讓我引用MSDN(source):

你不能聲明一個字段,屬性,事件或方法的返回類型爲具有匿名類型

但他們不說爲什麼。

所以問題仍然存在:爲什麼你不能聲明一個字段和屬性具有匿名類型?爲什麼.NET創作者從該選項中剝離它?

我從這裏得到警告,我的問題看起來很主觀,但我認爲它根本就不是 - 需要有客觀的理由。

至於我,我沒有看到任何障礙,但不知何故它不被支持。由於編譯器可以很容易地爲類的字段或屬性生成類型,與本地變量相同。

我的選擇是使用dynamic類型,但不幸的是我正在使用的單聲道引擎被剝離。

而且對我的選擇是使用對象類型和使用後反射來查找這些字段:

private static readonly object MAPPING = new 
{ 
    ssdungf = "flydung", 
    ssdungt = "flydung", 
    superfutter = "superfeed" 
}; 

但是,使用反射是這種情況是骯髒的,我會說。

我試圖找到答案,但我真的沒有找到任何答案。這裏有一些SO回答類似的問題,但他們沒有回答爲什麼:

Can a class property/field be of anonymous type in C# 4.0?

Declaring a LIST variable of an anonymous type in C#

How do you declare a Func with an anonymous return type?

+0

@HimBromBeere真的,我沒有想過,但仍然是領域。 –

回答

1

爲什麼你不能聲明一個字段和屬性具有匿名類型?

由於C#是靜態類型的,所以任何內存位置都必須被賦予一個類型,並且聲明會這樣做。對於本地人,我們可以從上下文中推斷出它是否與var聲明同時被初始化,但是即使類型沒有名稱,該類型也是可用的簡寫形式。

具有匿名類型的字段,即靜態綁定但不可描述的類型意味着什麼?

dynamic確實是最接近的類比你移植代碼,但因爲這是不提供給你,你可能會考慮使用IDictionary<string, object>(這亦是怎麼ExpandoObject,這是經常與dynamic曾經有過的對象表現得更像javascrpt對象,在幕後工作)。與創建需要的對象的類相比,這會更慢,更安全,但可以工作。

+0

感謝您的回答,我覺得這是最有價值的。你寫了「因爲C#是靜態類型的,所以任何內存位置都必須被賦予一個類型,並且聲明是這樣做的」,但編譯器可以做同樣的技巧來創建隱藏的類型,並且內存位置將具有類型。也許我不完全理解你的答案。 –

+0

但那麼在代碼中使用它意味着什麼呢? 「有一件事你不知道如何使用'_someField'」?好的,我們可以使用'var',但是如果程序員不知道它是什麼類型,除了查看一些(可能不可用的)源代碼,它對於程序員來說並不是非常有用。 –

+0

現在我明白你的觀點。謝謝。 –

0

上anoynmous財產的問題是:你如何獲得/套它?

假設它的工作:

class MyClass 
{ 
    public MyField = new { TheValue = "Hello World" }; 
} 

現在,在您消費代碼you'd寫代碼閱讀代碼:

MyClass m = new MyClass(); 
m.MyField.TheValue = "newValue"; 

這怎麼從具有MyField類型不同?所有你得到的是,你可以省略兩三行代碼,同時什麼都不做。但是我認爲你可能會產生很多問題,因爲沒有人知道他可以分配給哪個成員。

此外,你不能用匿名對象做很多事情,基本上你可以設置它並閱讀它。沒有任何方法(除了從object繼承的EqualsGetHashCode),您可以打電話以便機會非常低。

最後但並非最不重要的一個匿名對象通常用作臨時的,例如在一個Select -statement中。當你使用它時,你會說:這種類型只會在當前的特定範圍內使用,並且可以被整個世界忽略爲內部實現細節。創建匿名類型的屬性會將這樣的細節暴露給外部。當然,你可以爭辯說,設計師至少可以讓他們成爲private成員,但我想這樣做可以繞過完全無法訪問的概念。

+0

謝謝,你的最後一點是好的。但是你認爲這就是爲什麼.NET創作者不會這麼做的原因? –

+0

@JerrySwitalski只有他們會知道。 – HimBromBeere

相關問題