3

始める前に、誰かが提案したり質問したりする前に、混乱を解消させてください..

この質問は、Windows Phone 7 ではなく「Windows Mobile 6 Professional」に関連しており、古いデバイスに移行する必要があるため、Windows Phone 7 に移植することはできません。

さて、それはさておき...

私は現在、Windows Mobile 6 デバイスで実行するためのソースを持っている C# ライブラリを移植しようとしています。今、それは反射です。

.NET コンパクト フレームワークにはいくつかの制限があることは誰もが知っています。「System.Reflection」名前空間の多くのメソッドとプロパティがサポートされていないこともその 1 つです。

ライブラリの実際のデスクトップ バージョンは .NET V2.0 をターゲットにするように設定されており、.NET 3.5 SP1 を実行しているデバイスを使用しているため、ほとんどの場合、動作させるのにほとんど問題はありませんでしたが、そうは見えません。次の 2 つのコード チャンクを機能させるための賢明な方法を見つけます。

        var a = AppDomain.CurrentDomain**.GetAssemblies**();
        foreach (var assembly in a)
        {
            if (assembly is System.Reflection**.Emit.**AssemblyBuilder) continue;
            if (assembly**.GetType().**FullName == "System.Reflection.Emit.InternalAssemblyBuilder") continue;
            if (assembly**.GlobalAssemblyCache** && assembly**.CodeBase** == Assembly.GetExecutingAssembly()**.CodeBase**) continue;

            foreach (var t in GetLoadableTypes(assembly))
            {
                if (t.IsInterface) continue;
                if (t.IsAbstract) continue;
                if (t.IsNotPublic) continue;
                if (!typeof(IGeometryServices).IsAssignableFrom(t)) continue;

                var constuctors = t.GetConstructors();
                foreach (var constructorInfo in constuctors)
                {
                    if (constructorInfo.IsPublic && constructorInfo.GetParameters().Length == 0)
                        return (IGeometryServices)Activator.CreateInstance(t);
                }
            }
        }

        catch (**ReflectionTypeLoadException** ex)
        {
            var types = ex**.Types**;
            IList<Type> list = new List<Type>(types**.Length**);
            foreach (var t in types)
                if (t != null && t**.IsPublic**)
                    list.Add(t);
            return list;
        }

具体的には、上記のコードで太字で示されている項目は、コンパクト フレームワークには存在しないように見えるメソッドとプロパティです。インテリセンスとオブジェクト ブラウザーでかなりの時間を費やした後、私は何も見つけられませんでした。同じ型を返します (または利用可能にします)。

私の質問は次のとおりです。

Compact .NET フレームワークでリフレクションを使用した経験があり、このコードを期待どおりに動作させる方法を提案できる人はいますか?それとも、不足しているメソッドを置き換えるためにカスタム スタブと機能を書き始める必要がありますか?

フレームワークにはいくつかのリフレクション機能があることを知っているので、それを達成する同等の方法があるはずです。

コードを認識できる人のために、最後のメモとして。はい、それは .NET トポロジ スイートからのものであり、はい、私が WM6 バージョンをビルドしようとしているライブラリです。そのため、既にそれを行っている人を知っている場合は、その旨をコメントしてください。簡単な方法を見てみましょう:-)

================================================== ====================

投稿後に更新

「太字」のテキストはコード スニペットでは機能しないようです。そのため、上記のコードで ** で囲まれているメソッド/プロパティは、太字にする必要がある部分です。

4

1 に答える 1

1

そのため、いくつかの古いビルドと実験的な Silverlight ビルドを調査した後 (これには明らかに Windows Mobile / CE と同じ制限がたくさんあります)。

魔法が効く方法がわかりました。

最初の部分は、検索するアセンブリを表す 'Assembly' 構造で配列を埋めることでした。もともとは次のとおりでした。

var a = AppDomain.CurrentDomain.GetAssemblies(); 

ただし、GetAssembliesは WM に存在しないため、最も簡単な方法は次を使用することです。

var a = new[] {Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly()}; 

私の場合、これは 2 つの同一のアセンブリを取得したことを意味しますが、GeoAPI を使用するメインの exe からアセンブリを呼び出すと、2 つの異なるアセンブリがここに表示されます。

次の課題は、チェックする必要のないアセンブリを「取り除く」ことでした。

if (assembly is System.Reflection.Emit.AssemblyBuilder) continue; 

if (assembly.GetType().FullName == System.Reflection.Emit.InternalAssemblyBuilder") continue; 

if (assembly.GlobalAssemblyCache && assembly.CodeBase == Assembly.GetExecutingAssembly().CodeBase) continue; 

1 番目と 2 番目のインスタンスは WM6 では発生しないため、コメント アウトするだけで安全です。2 番目のものは機能しますが、WM6 では指定されたチェック名 (欠落しているため) を持つアセンブリは表示されないため、コメントアウトしても安全です。コメントアウトしませんでしたが、true としてトリガーされることもありませんでした。

最後の部分 (少なくとも元のパズルがとにかく行った限り) は次のとおりです。

foreach (var t in GetLoadableTypes(assembly)) 
{ 
  if (t.IsInterface) continue; 
  if (t.IsAbstract) continue; 
  if (t.IsNotPublic) continue; 
  if (!typeof(IGeometryServices).IsAssignableFrom(t)) continue; 

私の最初の試みでは、' isInterface ' & ' isNotPublic ' が欠落していましたが、上記の ' var a ' 変数の内容を期待されるデータ型で修正することができたら、何も欠落することなくすべてが正常に動作し始めました。

最後の質問は?これですべて解決しましたか?まあ、そうではありません....

GeoAPI の「 ReflectInstance 」メソッドの全体的な目的は、「IGeometryServices 」インターフェイスを使用してユーザー定義の「GeometryFactory 」を見つけることでした。

呼び出し元のアセンブリのみを反映していたため (上記の var a)、「NetTopologySuite」(ジオメトリ ファクトリが定義されている場所) は選択リストに追加されませんでした (明らかに CurrentDomain.GetAssemblies にはこれが含まれています)。

最終的な結果は、正しいタイプのアセンブリが見つからなかったため、最後に例外が発生することになりました。

ただし、 GeoAPI の「Geometry 」コンストラクターには、 GeometryFactoryを渡すことができるオーバーロードがあり、これを行うと、 ReflectInstance メソッドを完全に無視し、指示されたものだけを使用します。

別の言い方をすれば、そもそもこれを行う必要はありませんでした。メソッドを「null」を返すように設定し、使用したいジオメトリ ファクトリを渡すだけで済みました。

とにかく、誰かが興味を持っているなら、私は今の作業コピーを持っています:

GeoAPI.NET NetTopologySuite Wintellect.PowerCollections

.NET CF 3.5 を使用する Windows Mobile 6 および Windows CE で正常にビルドおよび動作します。

于 2012-10-03T09:42:38.210 に答える