簡體   English   中英

C#是否與Scala的結構類型相當?

[英]Does C# have an equivalent to Scala's structural typing?

在Scala中,我可以定義結構類型如下:

type Pressable = { def press(): Unit }

這意味着我可以定義一個函數或方法,它將一個可壓縮的參數作為參數,如下所示:

def foo(i: Pressable) { // etc.

我傳遞給這個函數的對象必須為它定義一個名為press()的方法,該方法匹配類型中定義的類型簽名 - 不帶參數,返回Unit(Scala的void版本)。

我甚至可以使用結構類型內聯:

def foo(i: { def press(): Unit }) { // etc.

它基本上允許程序員擁有鴨子類型的所有好處,同時仍然具有編譯時類型檢查的好處。

C#有類似的東西嗎? 我用谷歌搜索但找不到任何東西,但我不熟悉C#的任何深度。 如果沒有,有沒有計划添加這個?

不,我也不知道。 僅命名(而不是結構)子類型(例如接口)。

(其他人可能也希望看到

http://en.wikipedia.org/wiki/Nominative_type_system

http://en.wikipedia.org/wiki/Structural_type_system

(有些人可能會指出一些異國情調的案例,比如使用結構類型為GetEnumeratorforeach語句,但這是例外而不是規則。)

沒有辦法定義具有特定功能的結構類型。 有一個庫可以為C#添加鴨子打字支持,可以在這里找到。

這是Duck Typing項目的例子。 請注意鴨子類型在運行時發生並且可能失敗 我也理解這個庫為鴨子類型生成代理,這與Scala中享受的優雅編譯時支持相去甚遠。 這很可能與這一代C#一樣好。

public interface ICanAdd
{
    int Add(int x, int y);
}

// Note that MyAdder does NOT implement ICanAdd, 
// but it does define an Add method like the one in ICanAdd:
public class MyAdder
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

public class Program
{
    void Main()
    {
        MyAdder myAdder = new MyAdder();

        // Even though ICanAdd is not implemented by MyAdder, 
        // we can duck cast it because it implements all the members:
        ICanAdd adder = DuckTyping.Cast<ICanAdd>(myAdder);

        // Now we can call adder as you would any ICanAdd object.
        // Transparently, this call is being forwarded to myAdder.
        int sum = adder.Add(2, 2);
    }
}

這是使用良好的無聊接口實現相同功能的C#方式。

interface IPressable {
  void Press();
}

class Foo {
 void Bar(IPressable pressable) {
    pressable.Press();
 }
}

class Thingy : IPressable, IPushable, etc {
 public void Press() {
 }
}

static class Program {
 public static void Main() {
  pressable = new Thingy();
  new Foo().Bar(pressable);
 }
}

正如其他人所指出的那樣,這在.NET中並不真正可用(因為這更像是運行時而不是語言)。 但是,.NET 4.0支持導入的COM接口類似的東西,我相信這可以用於實現.NET的結構類型。 看到這篇博文:

我自己還沒有嘗試過這個,但我認為這可能使編譯器作者能夠編寫.NET結構類型的語言。 (這個想法是你(或編譯器)會在場景后面定義一個接口,但是它會起作用,因為由於COM等價特性,接口將被視為等價的)。

此外,C#4.0支持dynamic關鍵字,我認為可以將其解釋為結構類型(沒有靜態類型檢查)。 該關鍵字允許您在不知道(在編譯時)對象是否具有所需方法的情況下調用任何對象上的方法。 這與Igor提到的“Duck typing”項目基本相同(但當然,這不是一個正確的結構類型)。

C#中的等待模式可能被解釋為結構子類型/存在性類型的有限的臨時實例。 編譯器將只await有權訪問GetAwaiter()方法的對象,該方法返回具有一組特定方法和屬性的任何INotifyCompletion對象。 由於'awaitable'對象和'awaiter'對象都不需要實現任何接口(在后者的情況下除了INotifyCompletion ), await類似於接受結構類型的等待對象的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM