2016-09-12 5 views
4

グラフィックスAPI Gは、任意の外部数学ライブラリに依存したくないため、すべてのベクトルパラメータをベア構造体(like SharpDX does with its raw types)として定義しています。アセンブリGとMの型の間でアセンブリAに暗黙の演算子を追加できますか?

数学ライブラリもあります。Mです。

開発者は、グラフィックスAPI Ganother sample from SharpDX, but in this case the operators are defined in M instead of A)からの生タイプに数学ライブラリから完全な形の間Mをキャストする暗黙のオペレータに組み立てを提供したいと考えています。両方の型がまったく同じメモリ表現を持つことに注意してください。


Afaikでは、このような演算子を提供する手段はC#言語ではありません。気になるのは拡張メソッドですが、ユーザーは変換を行うためにさらにメソッドを呼び出す必要があります。

このような演算子のサンプルは、ILリライトによって追加できますか?私の限られた知識から、私はそれが可能だと思うだろうが、問題に関する追加のフィードバックを感謝します。

ありがとうございます!

+3

これは、間接的なレイヤーを追加することで可能です。中間アセンブリで、暗黙の操作のホストとして動作する型を定義します。 –

+0

I Second that @JonathonChase –

+0

@JonathonChase私は、C#キャスト演算子解決メカニズムが変換演算子の*チェーン*を探すのではないかと確信しています。エリック・リッペルトのような人にも記事があったと思う。暗黙の演算子はそれほどトリッキーです:) – Luaan

答えて

1

これは、2つのライブラリの1つのILを書き換えることで可能です。具体的には、暗黙の演算子をその型に追加します(プロセスでは他のライブラリにも依存関係を追加します)。

しかし、これは悪い考えです。つまり、ライブラリの独自のバージョン(つまり、NuGetのバージョンを使うことはできません)を使用する必要があり、アップグレードするたびに、再度ILリライタを実行する必要があります。

私には、Foo(bar.ToBaz())の代わりにFoo(bar)と書くことができます。

1

私のコメントを拡大して、ここでは非常に単純化された例です。基本的には、2つのタイプを同じ意味で使用できるようにすることです。私たちはこれをどのように達成しますか?第3のタイプを追加することによって。その後、アプリケーションのすべてのロジックを新しい型の観点から定義し、外部ライブラリへの呼び出しをラップします。

// External Assemblies A and B define the following types: 

// Assembly A 
public class X 
{ 
    public string Name { get; set; } 
    public static void SomeFunction(X item) 
    { 
     Console.WriteLine($"X.{item.Name}"); 
    } 
} 

// Assembly B 
public class Y 
{ 
    public string Name { get; set; } 
    public static void SomeFunction(Y item) 
    { 
     Console.WriteLine($"Y.{item.Name}"); 
    } 
} 

// We would create an implicit intermediary in intermediate assembly C 

// Assembly C 
public class Z 
{ 
    public string Name { get; set; } 
    public static implicit operator Z(X input) => new Z { Name = input.Name }; 
    public static implicit operator X(Z input) => new X { Name = input.Name }; 
    public static implicit operator Z(Y input) => new Z { Name = input.Name }; 
    public static implicit operator Y(Z input) => new Y { Name = input.Name }; 
} 

public void PushToX(Z thing) => X.SomeFunction(thing); 

public void PushToY(Z thing) => Y.SomeFunction(thing); 

public void DoThing(Z thing) 
{ 
    Console.WriteLine(thing.Name); 
} 

public void Main() 
{ 
    var a = new X { Name = "A" }; 
    var b = new Y { Name = "B" }; 
    DoThing(a); 
    DoThing(b); 
    PushToX(a); 
    PushToY(a); 
    PushToX(b); 
    PushToY(b); 

    //A 
    //B 
    //X.A 
    //Y.A 
    //X.B 
    //Y.B 
} 
関連する問題