2

計画

WCFのサブセットを置き換えるために使用されるリモーティングクラスを開発しました。これは、Unity3Dを使用してモバイルプラットフォームをターゲットにしており、メモリ消費を可能な限り小さく保つ必要があるためです。(したがって、実際には2.7MBのサイズのSystem.ServiceModelを含める必要はありません。これは、小さなモバイルRAMには十分です

現在、すべてのタイプ(数年前に作成された独自のシリアライザーを使用してシリアル化される複雑なタイプを含む)で正常に動作し、複雑な状況(AがBを呼び出す、BがAを呼び出す、Aが何かを返す、Bが何かを返す)を処理することもできます。

メソッドの呼び出し

私が使用しているターゲットサイトでメソッドを呼び出すためにType.InvokeMember、null許容型を除いてほとんどの場合に実際に機能します。そして、これは私が直面した問題です。私のインターフェース定義では、メソッドは次のようになります。

public interface IServerContract 
{
    void SetUsageID(Int32? id);
}

ServerProxyリモートメソッドの呼び出しを処理するオブジェクト)私は次のことを行っています:

public class ServerProxy : ProxyBase
{
    public void SetUsageID(Int32? id)
    {
         RemoteCall("SetUsageID", id);
    }
}

の定義は次のようになっているため、通常どおり、パラメータidはボックスで囲まれています。RemoteCall

public void RemoteCall(String methodName, params Object[] arguments) { ... }

この時点で、私はaだけを取得しSystem.Int32、null許容型はもう取得していません。引数をシリアル化し、ターゲットマシンで逆シリアル化します。この時点で私は呼び出していますが、これは例外を引き起こします。これは、彼が最初のパラメーターとして(これを無視しない場合は2番目の)パラメーターType.InvokeMethodをとるメソッドを見つけることができないためです。Int32

この問題の最善の解決策は何ですか?サーバルの方法はありますが、すべてパフォーマンスに影響を与えます。

4

1 に答える 1

2

のボクシングのルールは、int?実際にあなたがそれをあなたが見るように持っているとそれを意味しobjectます:

  • 空の値はnullであり、それ以上は識別できません
  • 空でない値は、null許容型としてのみ知られています
    • 具体的には、通過する(int)5と、内部(int?)5まったく同じ外観になりますobject

そのため、利用可能なオプションは次のとおりです。

  • メソッド名が一意であることを確認して、名前で一意に解決してからMethodInfo使用できるようにしますMethodInfo.Invoke(これにより、パラメーターにあいまいさがなくなります)
  • null許容型ではない型を受け入れるメソッドを解決してから、代わりにnull許容型を探してください(マルチパラメーターメソッドの場合は複雑になります)
  • 呼び出しているメソッドに関するメタデータをさらに渡す(サイズを大きくする)

個人的には、しかし、私はそのようなことについて非常に単純な見方をしています...漠然としたマルチパラメータメソッドをエンコードしようとするのではなく、別のオプションは、常に単一のDTOベースのパラメータを渡すように単純化することです-つまり、SetUsageID(int?)あなたの代わりにhave SetUsage(SetUsageArgs)(または同様のもの)。SetUsageArgsたまたま単一のプロパティがあります。重要なのは、単一のDTOをエンコードしているだけであり、そのDTOを逆シリアル化すると、あいまいさはなくなります。

于 2012-04-23T09:36:31.657 に答える