19

Scala では、次のように構造型を定義できます。

type Pressable = { def press(): Unit }

これは、次のように、Pressable である何かを引数として取る関数またはメソッドを定義できることを意味します。

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

この関数に渡すオブジェクトは、その型で定義された型シグネチャに一致する press() というメソッドを定義している必要があります。引数をとらず、Unit (Scala バージョンの void) を返します。

構造型をインラインで使用することもできます。

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

基本的に、プログラマーはダックタイピングのすべての利点を享受しながら、コンパイル時の型チェックの利点を得ることができます。

C# には似たようなものがありますか? 私はグーグルで検索しましたが、何も見つかりませんでしたが、C# について詳しく知りません。ない場合、これを追加する予定はありますか?

4

4 に答える 4

11

いいえ、私が知っている計画はありません。名前付き (構造的ではなく) サブタイピング (例: インターフェイス) のみ。

(他の人も見たいかもしれません

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

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

)

foreach( の構造型付けを使用するステートメントのような、風変わりな特殊なケースを指摘する人もいるかもしれませんGetEnumeratorが、これは規則ではなく例外です。)

于 2010-05-14T00:44:47.913 に答える
7

特定の機能を持つ構造型を定義する方法はありません。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);
 }
}
于 2010-05-14T00:48:48.527 に答える
5

他の人が指摘したように、これは .NET では実際には利用できませ(これは言語よりもランタイムの問題であるため)。ただし、.NET 4.0 は、インポートされた COM インターフェイスに対して同様のことをサポートしており、これを使用して .NET の構造型付けを実装できると思います。このブログ投稿を参照してください。

私はまだこれを自分で試したことはありませんが、コンパイラの作成者が .NET の構造型付けを使用して言語を記述できるようになる可能性があると思います。(アイデアは、あなた (またはコンパイラ) が舞台裏でインターフェイスを定義するというものですが、COM 等価機能のおかげでインターフェイスが同等として扱われるため、機能します)。

また、C# 4.0 はdynamic、構造的な型付け (静的な型チェックなし) として解釈される可能性があるキーワードをサポートしています。このキーワードを使用すると、(コンパイル時に) オブジェクトに必要なメソッドがあるかどうかを知らなくても、任意のオブジェクトのメソッドを呼び出すことができます。これは本質的に、Igor が言及した「ダック タイピング」プロジェクトと同じものです (もちろん、これは適切な構造タイピングではありません)。

于 2010-05-14T00:54:31.897 に答える