DOBON.NETプログラミング道掲示板

■ 「新規作成」から投稿できます。
■ マルチポストされた投稿を見つけたときは、その投稿に返信することによりご報告ください。その際は匿名で投稿し、マルチポストされている場所を併記してください。
■ スパム対策のため、メールアドレスの先頭に"_"という文字が付加されています。
RSS 2.0 RSS 2.0 | RSS 0.91 | 携帯電話用 | 自分専用のアイコンを使用するには | 掲示板への要望 | 管理人に連絡 | お気楽掲示板
■ 24時間以内に作成されたスレッドは New で表示されます。
■ 24時間以内に更新されたスレッドは UpDate で表示されます。

記事リスト ( )内の数字はレス数
Nomal参照dllへの文字列引数をutf8で渡したい。(13) | NomalFILE.COPYでIOExceptionエラーが出る(11) | Nomalリストを別フォームに渡す方法(9) | Nomal例外発生した場合に変数をcatchに渡したい(9) | NomalCode128でバーコードが読み取れない(8) | Nomalモードレスフォーム Warning IDE0067を回避したい(7) | NomalIE11では表示されるが、.netのWebBrowserでは、表示されないHPを表示する方法(7) | Nomal数字だけで構成されてるCSVフィールドが自動的に数値として解釈される(7) | NomalフォームコントロールへのDataBindingsでプロパティが相互反映されない(7) | Nomal起動ディスプレイの指定方法について(6) | NomalListBoxにデータが表示されない(6) | Nomal文字列を8bit に戻してから UTF-8 に変換する方法(6) | NomalSQLServerテーブル内容をDataGridViewに表示するコードについて(6) | Nomal文字列構造体のListのソート(6) | NomalWebBrowser Controlを使って、任意の値を取得(5) | Nomalこんな演算子初めて見ました。(5) | NomalRichTextBoxで入力文字の自動折り返しを止めたい(5) | NomalあるWindows10PCでビルドしたEXEがW8.1以下で実行エラー(5) | Nomalポルトガル語の登録(5) | Nomaloo4oのAddTableをADOに移行したい(5) | NomalDeclare宣言するdllと参照追加をするdllの区別(4) | NomalVS2017で作成されたDLLをVS2005で作成されたAPで使用する方法(4) | Nomalフォルダ内の全ての容量を取得したい(4) | Nomal共変性と反変性ってこういうこと?(4) | Nomalプロセスからウインドウを取得(4) | NomalNewの使い方間違ってますか?(4) | Nomalユーザーコントロール内のテキストボックスのmodifiedプロパティ(4) | NomalJOIN操作の構文エラー(4) | Nomal動的にプロパティや変数の値の取得(4) | NomalVB6 ほかのアプリケーションを起動し そのアプリケーションは終了させる方法(4) | Nomalスクロールバーが出た時に高さを変えたい(4) | NomalDatagridViewの行高さ変更について(4) | NomalLINQのメソッド構文の書き方(3) | Nomalvb.net+SQLiteで複数データベースファイルへのトランザクション方法(3) | Nomalジェネリック型インターフェースを使った変数を扱いたい(3) | NomalProcess.WaitForExitで正常に動作しない?(3) | NomalPictureBox.Locationのキャンセル(3) | NomalCatch時のex.StackTraceの情報(3) | NomalVisualStudioでマクロ(3) | NomalOracleDataAccess を参照したプログラムでデバッグモードが機能しなくなる(3) | NomalVisualStudioでExcelのVSTO開発(3) | NomalVB.NETでCSVを読み込む際にSQL文を使いたい(3) | NomalDrawImage でメモリ不足エラー(3) | NomalVb.netからAccessへの接続について(3) | Nomal令和の日付への対応(3) | NomalHTTP 417エラーを発生させるためのIIS設定はどうすればよいか(3) | NomalDrawString前のFillRectangle有無により文字の太さが違う理由について教えて下さい(3) | NomalPIctureBox同士を論理合成したい(3) | Nomalデータセット定義ファイルからDataTable(3) | Nomalネットの画像の複数枚を重ね合わせたい(3) | NomalDataGridViewで検索をかける方法(3) | NomalDataGridViewの選択時の色を透明にしたい(3) | NomalWebBrowserでWebページからのメッセージ(3) | NomalASP.NETから呼ばれているかどうか判定する方法(3) | NomalCA2213の警告が消えません(3) | NomalC# 現在のコンテキスト内にxxxという文字は存在しませんと出ます(3) | NomalTaskクラスを.NET Framework 2.0で実現させる方法(2) | NomalWebBrowser Control foreachで値が消える(2) | NomalEditボックスに簡体字をセットする方法(2) | NomalWebClientが上手く動かない(2) | Nomalフォーム外のカーソルの変更(2) | Nomalラムダ式の勉強中(2) | NomalRichTextBoxで入力文字の自動折り返しを止めたい(2) | NomalC#をVBに変換(2) | NomalWebClientで、短期間にDownloadStringAsyncを実行したい(2) | NomalマウスのないOSでマウスカーソルの表示(2) | NomalToolStripMenuItemにShortcutKeysを指定した際の、元のコントロールを取得する方法(2) | NomalMouseEventArgsのカレント座標(2) | Nomalリッチテキストボックスでの字間の調整(2) | NomalVC++ → VB.Netに変換時に文法エラー(2) | NomalSQL-Server Compact 4.0が表示されない(2) | Nomalバーコードの数字を非表示にしたい(2) | Nomal自作したアプリの発行元を明記したい(2) | NomalSystem.Threading.Thread.Sleep()と変数(2) | NomalDataGridView 行の背景色の設定(2) | NomalDatagridviewのクリア(2) | NomalnumericUpDwonコントロールのvalue(2) | NomalVisual Studio DataTableの値のアクセスの仕方(2) | NomalDataTableの構造が同じか調べるメソッド(2) | NomalRejectChangesについて(2) | NomalPC機種によってスタートアップ画面が中央から左上にずれる、Fontがおかしくなる。(2) | Nomalタスクスケジュール登録時の例外メッセージ(2) | Nomal管理者モードでクリック(2) | NomalVB2017でのインストーラ作成時のエラーについて(2) | NomalMicrosoft Azure OCRのサンプルコード実行時エラー(2) | Nomalデータバインド時のDataGridViewのカスタムソート(2) | NomalObject型からDecimalへの変換(2) | Nomal擬似言語をVBのプログラミングに変換(2) | Nomalユーザーコントロールのプロパティが保存されない(2) | NomalWindows10(1803)からGetHostEntryでipv4が取得出来ない場合がある(2) | Nomal自分自身を呼び出すのはOKですか(1) | NomalList型でエラーが起きてしまい・・・(1) | NomalLINQの拡張メソッドの定義(1) | NomalWebRequest でメモリが解放されない(1) | NomalFunction プロシージャからの文字選択(1) | NomalRDP接続でのネットワーク帯域制限(0) | Nomal必須コンポーネントの一覧に追加したい(0) | NomalApp.configのMy.Application.Log設定で使用できない属性が出る(0) | Nomalvb2010を使用したmicrosoft Wordの任意の行の削除(0) | NomalWinFormsでWindows10のカメラアプリと連携したい(0) |



■記事リスト / ▼下のスレッド
■34446 / 親記事)  Declare宣言するdllと参照追加をするdllの区別
□投稿者/ nao 一般人(8回)-(2020/03/22(Sun) 17:15:45)
  • アイコン環境/言語:[VB.NET .NET Framework2.0] 
    分類:[.NET] 

    Declare宣言をしなければならないdllと、参照に追加するするだけで使用できるdllの違いは何でしょうか。
    どうやって区別したらよいのでしょうか。

    参照に追加するだけで使用できるdllもDeclare宣言をすると参照に追加しないで使用できるようになる、またはDeclare宣言をしなければならないdllも参照に追加すると使用できるようになるということはあるのでしょうか。

    よろしくお願いいたします。
違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34447 / ResNo.1)  Re[1]: Declare宣言するdllと参照追加をするdllの区別
□投稿者/ Azulean 大御所(514回)-(2020/03/22(Sun) 18:49:52)
  • アイコンNo34446に返信(naoさんの記事)
    > Declare宣言をしなければならないdll
    昔ながらの C 言語ベースの関数エクスポートがされている DLL を呼び出す際に使います。
    DLL 側には引数や戻り値に関する情報がないので、自分で引数や戻り値を定義する必要があります。


    > 参照に追加するするだけで使用できるdll
    主に .NET で作成された DLL です。
    型に関するメタデータが埋め込まれているので、どんな型があり、どんなメソッドがあるか、引数が何であるかなどもわかるようになっています。


    > どうやって区別したらよいのでしょうか。
    基本的にはその DLL のドキュメントを見ることではないでしょうか?
    試しに参照に追加するでも良いとは思いますが…。


    > 参照に追加するだけで使用できるdllもDeclare宣言をすると参照に追加しないで使用できるようになる、またはDeclare宣言をしなければならないdllも参照に追加すると使用できるようになるということはあるのでしょうか。

    原則的にありません。
    .NET の DLL は関数エクスポートがサポートされていないので、参照設定に追加するしかありません。

    // おそらく、Task 話と .NET 2.0 問題からの思いつきだと思いますが、Declare で逃げることはできません。
    // C++/CLI にチャレンジされるなら、話は別ですが。
違反を報告
引用返信
■34448 / ResNo.2)  Re[2]: Declare宣言するdllと参照追加をするdllの区別
□投稿者/ nao 一般人(9回)-(2020/03/22(Sun) 19:02:18)
  • アイコンご回答ありがとうございます。

    やはりdllだけでは区別はつかないのですね。

    > // おそらく、Task 話と .NET 2.0 問題からの思いつきだと思いますが、Declare で逃げることはできません。
    お察しの通りです。
    納期が近く、今から作成しなおしは辛いので、Declareで使用できないかと考えた次第です。
    やはり無理なのですね。

    ありがとうございました。

解決み!
違反を報告
引用返信
■34449 / ResNo.3)  Re[3]: Declare宣言するdllと参照追加をするdllの区別
□投稿者/ Azulean 大御所(515回)-(2020/03/22(Sun) 19:06:51)
  • アイコン2020/03/22(Sun) 19:07:49 編集(投稿者)

    No34448に返信(naoさんの記事)
    > 納期が近く、今から作成しなおしは辛いので、Declareで使用できないかと考えた次第です。
    > やはり無理なのですね。

    リスケか、.NET 2.0 世代のノウハウを持つ人材の投入か、何らかの策を早めに交渉・調整した方が良いと思います。
    .NET 2.0 時代のノウハウがない状態で、.NET 2.0 向けに同等仕様の安定した品質を短期間にリリースすることは無茶なので…。
解決み!
違反を報告
引用返信
■34450 / ResNo.4)  Re[4]: Declare宣言するdllと参照追加をするdllの区別
□投稿者/ nao 一般人(10回)-(2020/03/22(Sun) 19:14:00)
  • アイコン> リスケか、.NET 2.0 世代のノウハウを持つ人材の投入か、何らかの策を早めに交渉・調整した方が良いと思います。

    そうですよね。相談します。
    ありがとうございます。
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34438 / 親記事)  VS2017で作成されたDLLをVS2005で作成されたAPで使用する方法
□投稿者/ nao 一般人(1回)-(2020/03/20(Fri) 19:08:10)
  • アイコン環境/言語:[環境:Windows10 64bit、Windows7 32bit 言語:VB.NET ] 
    分類:[.NET] 

    初めまして。naoと申します。

    VB.NETでの開発で質問させていただきます。

    Visual Studio 2017(.NET Framework4.5.2)で作成したDLLをVisual Studio 2005(.NET Framework 2.0)で作成するアプリケーションで使用することはできないのでしょうか。

    VS2017でDLLを作成し、VS2005のアプリに「参照の追加」で追加したところ、
    「参照コンポーネント'[自作DLLの名称]'が見つかりませんでした」というエラーメッセージが表示されてしまいました。
    .NET Frameworkのバージョンの違いもしくはOSのbit数の違いのせいなのでしょうか。


    環境は以下の通りです

    VS2017:Windows10 64bit
    VS2005:Windows 7 32bit
違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34439 / ResNo.1)  Re[1]: VS2017で作成されたDLLをVS2005で作成されたAPで使用する方法
□投稿者/ Hongliang 大御所(574回)-(2020/03/20(Fri) 19:37:51)
  • アイコンDLLの方を.NET 3.5以下で作成すれば、多分参照できるようになります。
違反を報告
引用返信
■34440 / ResNo.2)  Re[2]: VS2017で作成されたDLLをVS2005で作成されたAPで使用する方法
□投稿者/ nao 一般人(2回)-(2020/03/20(Fri) 20:01:36)
  • アイコンNo34439に返信(Hongliangさんの記事)
    > DLLの方を.NET 3.5以下で作成すれば、多分参照できるようになります。

    ご回答いただきありがとうございます。

    .NET Frameworkのバージョンを変更するしか方法はありませんでしょうか。

    バージョンを変更してみましたが、.NET Framework 3.5では使用できないクラス(Taskクラス)を使用して作成されているのでエラーが出てしまいます。
    他の解決策はありませんでしょうか。

違反を報告
引用返信
■34441 / ResNo.3)  Re[3]: VS2017で作成されたDLLをVS2005で作成されたAPで使用する方法
□投稿者/ Hongliang 大御所(575回)-(2020/03/20(Fri) 21:15:15)
  • アイコン後はアプリケーションの方を.NET Framework 4以降でビルドすることですね。もちろんVisual Studio 2005では不可能なのでもっと新しいVisual Studioに移行するなりする必要がありますが。
違反を報告
引用返信
■34442 / ResNo.4)  Re[4]: VS2017で作成されたDLLをVS2005で作成されたAPで使用する方法
□投稿者/ nao 一般人(3回)-(2020/03/20(Fri) 21:24:55)
  • アイコンNo34441に返信(Hongliangさんの記事)
    > 後はアプリケーションの方を.NET Framework 4以降でビルドすることですね。もちろんVisual Studio 2005では不可能なのでもっと新しいVisual Studioに移行するなりする必要がありますが。

    ご回答ありがとうございます。

    やはりどちらかを合わせるしかありませんよね。

    ありがとうございました。
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34418 / 親記事)  フォルダ内の全ての容量を取得したい
□投稿者/ susu 一般人(1回)-(2020/01/01(Wed) 21:26:24)
  • アイコン環境/言語:[C#] 
    分類:[.NET] 

    お世話になります。
    C#でフォルダ内のファイル容量(サブフォルダ含め)を取得したいと思いますが
    DirectoryInfoを使うと遅いのでFileSyatemObjectのGetFolderを使いたく下記の
    ようにしましたが最後の行でHRESULT からの例外:0x800A0046とエラーになります
    何が悪いのでしょうか?よろしくお願いします。

    private long GetFolderSize(string path)
    {
      long size = -1;
    Scripting.FileSystemObject fso = new Scripting.FileSystemObject();
    Scripting.Folder Fd = fso.GetFolder(path);
    return Fd.Size;
    }
違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34419 / ResNo.1)  Re[1]: フォルダ内の全ての容量を取得したい
□投稿者/ jikoryuu 一般人(1回)-(2020/01/03(Fri) 13:20:38)
  • アイコンコードを試してみたところ特にエラーにはなりませんでした
    あと思い当たることはファイル容量がlongを超えている可能性があります
    double型にすれば問題を回避することができるはずです

    private double GetFolderSize(string path)
    {
    Scripting.FileSystemObject fso = new Scripting.FileSystemObject();
    Scripting.Folder Fd = fso.GetFolder(path);
    return Fd.Size;
    }
違反を報告
引用返信
■34420 / ResNo.2)  Re[2]: フォルダ内の全ての容量を取得したい
□投稿者/ Azulean 大御所(513回)-(2020/01/03(Fri) 17:28:13)
  • アイコンNo34418に返信(susuさんの記事)
    > 最後の行でHRESULT からの例外:0x800A0046とエラーになります
    > 何が悪いのでしょうか?

    0x800A0046 で検索すると "Scripting" を使った事例で "0x800A0046 (CTL_E_PERMISSIONDENIED)**" と書かれていますし、「配下にアクセス許可がないフォルダーがある」ということではないですか?
    もしくは、My Documents などの特殊なディレクトリがあるなど。

    こういった理由がある場合、Scripting.Folder の Size プロパティではやりたいことができないということになります。
    アクセス許可がない、あるいは特殊なフォルダーを飛ばして計算するようなコードを別途作っていただくことになりそうです。


    No34419に返信(jikoryuuさんの記事)
    > コードを試してみたところ特にエラーにはなりませんでした
    > あと思い当たることはファイル容量がlongを超えている可能性があります

    ちなみに、 C# の long 型は 64bit ですので、「long を超える」ということは「2 の 63 乗を超える、つまり 8PB(=8,192TB) を超える」ということになります。
違反を報告
引用返信
■34421 / ResNo.3)  Re[3]: フォルダ内の全ての容量を取得したい
□投稿者/ susu 一般人(2回)-(2020/01/04(Sat) 13:47:46)
  • アイコンjikoryuuさんAzuleanさんありがとうございます。
    「path」に「My Documents」を指定していました。別のフォルダでは問題なく
    容量を取得できました。特殊フォルダー等は加味しないことにしました。また
    念のためlong型をdouble型に変更しようと思います。
    ありがとうございました。
解決み!
違反を報告
引用返信
■34424 / ResNo.4)  Re[4]: フォルダ内の全ての容量を取得したい
□投稿者/ 魔界の仮面弁士 大御所(1273回)-(2020/01/06(Mon) 12:31:56)
  • アイコン
    No34418に返信(susuさんの記事)
    > C#でフォルダ内のファイル容量(サブフォルダ含め)を取得したいと思いますが
    
    Size プロパティで返される値は、必ずしも実際のディスク使用量とは
    一致していない点に御注意ください。
    (単にファイルサイズの論理合計を返しているのだと思います)
    https://www.haruru29.net/blog/storage-allocation-unit-size/
    
    
    
    ■No34421に返信(susuさんの記事)
    >>> long size = -1;
    > 念のためlong型をdouble型に変更しようと思います。
    
    FileSystemObject ライブラリにおいては、
    Folder オブジェクトの Size プロパティが、
    2 GiB を境に戻り値のデータ型が変わるようです。
    
    2147483647 以下の場合、int 型(C#) / Long 型(VBA)の値を返し、
    2147483648 以上の場合、double 型(C#) / Double 型(VBA) の値を返しました。
    
    
    
    参考までに、整数値を誤差無く保持するために使用できる
    C# の数値型と、それぞれの上限値を記しておきます。
    
    1:decimal 型なら『(2 の 96乗) - 1』バイトまで (約 65536 YiB )
    2:  ulong 型なら『(2 の 64乗) - 1』バイトまで(約 16 EiB)
    3:   long 型なら『(2 の 63乗) - 1』バイトまで(約 8 EiB)
    4: double 型なら『(2 の 53乗) - 1』バイトまで(約 8 PiB)
    5:   uint 型なら『(2 の 32乗) - 1』バイトまで(約 4 GiB)
    6:    int 型なら『(2 の 31乗) - 1』バイトまで(約 2 GiB)
    7:  float 型なら『(2 の 24乗) - 1』バイトまで(約 16 MiB)
    
    ----
    1:decimal 型[128bit] → 79,228,162,514,264,337,593,543,950,335
    2:  ulong 型 [64bit] → 18,446,744,073,709,551,615
    3:   long 型 [64bit] → 9,223,372,036,854,775,807
    4: double 型 [64bit] → 9,007,199,254,740,991
    5:   uint 型 [32bit] → 4,294,967,295
    6:    int 型 [32bit] → 2,147,483,647
    7:  float 型 [32bit] → 16,777,216

解決み!
421×580 => 181×250
イメージ
02.png
/14KB
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34410 / 親記事)  共変性と反変性ってこういうこと?
□投稿者/ VBはじめました 一般人(25回)-(2019/12/05(Thu) 13:36:59)
  • アイコン環境/言語:[VisualStudio2017 VB.net] 
    分類:[.NET] 

    ジェネリックを勉強していると、共変性と反変性ってでてきます。
    ググればググるほどよくわからなくなるのですが、次ような解釈で問題ないでしょうか?
    詳しい方いらっしゃいましたら教えて頂けないでしょうか?
    
    (以下、自分なりの解釈)
    ジェネリック型は、さまざまなデータ型に対して、同じ機能を実行させるために必要な処理を行うプログラミング機能を提供します。ジェネリック型のメソッドは、呼び出し側が提供するデータ型に合わせてデータ型を指定してインスタンスを作成して使用することになります。その際、完全にデータ型を合致させることが望ましいのですが、場合によってが、融通性を持たせたい場合が発生します。例えば、List<String>型データとArray型のデータに対して同じ機能を実行いたい場合、List<String>型とArray型に対するジェネリック型インスタンスをそれぞれ作って使用すればいいことになります。しかし、ジェネリック型メソッドがデータソースに求める機能が列挙をベースとしたものであれば、IEnumerable<String>型で定義すれば、一つのデリゲート定義でList<String>型とArray型のデータソースが受け取れるという融通性を得ることができます。この際、呼び出し側のデータ型と受け取り側のデータ型が異なるため、データ変換処理が発生します。List<T>クラス、Arrayクラスは、共にIEnumerable<T>を実装していますので、IEnumerable<T>と比べて強い派生型(狭い型)と言えます。即ち、強い派生型から弱い派生型への型変換がなされたということになります。その際に、データとしての互換性がある状況の場合を反変性があると言います。同様な状況は、メソッドからの返り値の受け渡しでも発生し、返り値の場合は、逆に弱い派生型から強い派生型へ変換する必要があり共変性といいます。次の例は、List(Of Integer)型,Array型をIEnumerable(Of Integer)型として受け取り、なんらかの処理をした後、IEnumerable(Of  Integer)型を返し、List(Of  Integer)型、Array型として受け取った。というものです。
    
    (サンプルコード)
       Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim myList As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5})
            Console.WriteLine("渡したデータ型は、{0}", myList.GetType)
            Dim RetList = Enume(myList)
            Console.WriteLine("返されたデータ型は、{0}", RetList.GetType)
            Console.WriteLine("---------")
            Dim myArray() As Integer = {1, 2, 3, 4, 5}
            Console.WriteLine("渡したデータ型は、{0}", myArray.GetType)
            Dim te2 = Enume(myArray)
            Console.WriteLine("返されたデータ型は、{0}", te2.GetType)
        End Sub
        Function Enume(MyEnume As IEnumerable(Of Integer)) 
                           As IEnumerable(Of Integer)
            Console.WriteLine("受け取ったデータ型は、{0}", MyEnume.GetType)
            '何らかの処理をしたと仮定
            Return MyEnume
        End Function
    
    解釈の内容が正しいのかと、サンプルとして適切かどうか?
    教えて頂けないでしょうか?

違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34411 / ResNo.1)  Re[1]: 共変性と反変性ってこういうこと?
□投稿者/ 魔界の仮面弁士 大御所(1268回)-(2019/12/06(Fri) 11:05:31)
  • アイコン2019/12/06(Fri) 20:03:48 編集(投稿者)

    No34410に返信(VBはじめましたさんの記事)
    > (以下、自分なりの解釈)
    改行無い 苦行じゃない?
    その説明 C# 混じってない?


    > 例えば、List<String>型データとArray型のデータに対して同じ機能を実行いたい場合、
    ここの文面は、List(Of String) に直したほうが良いですね。


    > メソッドからの返り値の受け渡しでも発生し、返り値の場合は、
    間違っているわけではないのですが、Return Value については、
    一般的には「戻り値」と呼びます。Microsoft の資料でもそうなっているはず。


    > 次ような解釈で問題ないでしょうか?
    概要としては間違っていないと思います。


    ただし『配列』については、まだジェネリックが無かった当時の名残で、
    特例措置として共変性を持つように設計されている点に注意して下さい。
    本来は、配列に関して共変性を認めるべきではないのですが、
    互換性の都合で、ここの仕様は変更できなかったのですね。

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Dim x() As List(Of Button) = Nothing
      'Dim y() As List(Of Control) = x 'これは NG(コンパイルエラー)

      Dim b() As Button = {Button1}
      Dim c() As Control = b '歴史的な事情から、配列は共変となっています


      'このような場合、書き込み(反変)は本来 NG ですが、コンパイルできてしまいます。
      'そのため、実行時に ArrayTypeMismatchException 例外となってしまいます。
      c(0) = Me '本来は List(Of ) 同様、コンパイル時に検出できるのが望ましい。
    End Sub



    > ジェネリックを勉強していると、共変性と反変性ってでてきます。

    これ自体はジェネリックに限定した用語では無いですね。

    『型の共変性』とは、広い型から狭い型へ変換が常に安全に行えること。(Covariance)
    『型の反変性』とは、狭い型から広い型へ変換が常に安全に行えること。(Contravariance)
    『型の双変性』とは、広い型にも狭い型にも変換できること。(Bivariance)
    『型の不変性』とは、型を変換できないこと。(Invariance)


    上記にある「広い型」や「狭い型」ですが、ジェネリックで使われる場合、
    たとえば Double と Integer などの関係性を示しているのではありません。

    ここでは継承・派生・インターフェイス実装などの関係性、たとえば
    「TextBox のインスタンスを Control 型の引数に代入しても問題無い」とか
    「Control 型の戻り値なプロパティから TextBox のインスタンスが取得されても問題無い」
    といった関係性を指しています。


    さて、VB2010 / C# 2010 からは、ジェネリックの型パラメーターに対して
    Out / out キーワードで共変性を、In / in キーワードで反変性を
    指定できるようになりました。
    『ジェネリックを勉強していると、共変性と反変性ってでてきます。』というのも
    それが要因でしょう。

    そのため、「ジェネリックにおける共変性と反変性」について学ぶのであれば、
    In/Out キーワードについても、合わせて学んでおくべきかと思います。

    ジェネリックの共変性と反変性について書かれた下記の記事でも、In や Out が出てきますね。
    https://www.atmarkit.co.jp/fdotnet/chushin/vb2010features_01/vb2010features_01_03.html



    提示頂いたサンプルにおいて、 IEnumerable(Of T) ジェネリック型インターフェイスが登場しています。
    この型についてヘルプで調べてみると、VB2008 (.NET Framework 3.5) までは
      Public Interface IEnumerable(Of T)
       Implements IEnumerable
    という定義であると書かれていたのに対し、VB2010 (.NET Framework 4) からは
      Public Interface IEnumerable(Of Out T)
       Implements IEnumerable
    であることが分かるはずです。Out が付与されたことで、共変性を明示することができます。

    一方、反変性の In については、Action(Of T) ジェネリック型デリゲートなどで使われています。
    VB2008 付属の .NET Framework 3.5 ヘルプでは
      Public Delegate Sub Action(Of T) (obj As T)
    という定義だったものが、.NET Framework 4 からは
      Public Delegate Sub Action(Of In T)(obj As T)
    という定義に変わっていますね。



    > サンプルとして適切かどうか?

    共変性と反変性の説明のためのサンプルとして書いたのであれば、
    どの部分が共変性で、
    どの部分が反変性を示しているのかを、
    コメントで説明した方が良いかと思います。


    また、Visual Basic のサンプルとしてなら、

    '『渡したデータ型は、System.Collections.Generic.List`1[System.Int32]』
    Console.WriteLine("渡したデータ型は、{0}", myList.GetType)
    '『渡したデータ型は、System.Int32[]』
    Console.WriteLine("渡したデータ型は、{0}", myArray.GetType)

    よりも

    '『渡したデータ型は、List(Of Integer)』
    Console.WriteLine("渡したデータ型は、{0}", TypeName(myList))
    '『渡したデータ型は、Integer()』
    Console.WriteLine("渡したデータ型は、{0}", TypeName(myArray))

    の方が分かりやすいと思います。


    それと、Function の宣言途中で改行する場合、
    「As IEnumerable(Of Integer)」の前に改行を入れてはいけません。
    改行するなら As の後に加えた方が良いでしょう。もしも As の前で改行したいなら、
    その前に行継続文字「 _」が必要なはずです。 (半角の空白とアンダーバー)
違反を報告
引用返信
■34412 / ResNo.2)  Re[2]: 共変性と反変性ってこういうこと?
□投稿者/ 魔界の仮面弁士 大御所(1269回)-(2019/12/06(Fri) 11:46:15)
  • アイコン2019/12/06(Fri) 20:08:09 編集(投稿者)

    No34411に補足(魔界の仮面弁士の記事)
    > https://www.atmarkit.co.jp/fdotnet/chushin/vb2010features_01/vb2010features_01_03.html

    Visual Basic におけるジェネリックの共変性と反変性については
    上記記事でも記載されていますが、追加で説明してみます。


    たとえば、
     Dim txt As TextBox = Me.TextBox1
     Dim item As Control = txt
    というコードが問題無いことは分かりますよね。
    TextBox は Cotrol を継承していますので、問題なく代入できるわけです。


    では何故、下記のコードはエラーになるのでしょう?

    Public Class Form1
      Private items As List(Of Control)

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim textBoxes As New List(Of TextBox)
        textBoxes.Add(Me.TextBox1)
        textBoxes.Add(Me.TextBox2)
        textBoxes.Add(Me.TextBox3)

        Me.items = textBoxes 'コンパイルエラー
      End Sub
    End Class


    TextBox 型は Control を継承しているので、一見問題無さそうに見えます。

    しかし、上記のような代入を認めてしまうと、
      Me.items(0) = Me.Button1
    のように、TextBox 以外のインスタンスに書き換えられてしまう恐れが生じます。

    Me.items が参照しているのが List(Of TextBox) のインスタンスだとしたら、
    そこに Button という、TextBox 以外のデータが格納されるのはマズイわけです。

    そのため、List(Of TextBox) のインスタンスを List(Of Control) 型の変数に
    代入することはできないように制限されています。
    ※その逆に、List(Of Control) 型のインスタンスを List(Of TextBox) 型に渡すのも駄目です。



    さて上記では、代入によって書き換えられるのが問題であるとされています。

    では、型パラメーターが「常に取得専用」でのみ使われる場合はどうでしょうか?
    items 変数の型を下記のように変更した場合は、エラーにはならずに済みます。

    Public Class Form1
      'Private items As List(Of Control)
      Private items As IEnumerable(Of Control)

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim textBoxes As New List(Of TextBox)
        textBoxes.Add(Me.TextBox1)
        textBoxes.Add(Me.TextBox2)
        textBoxes.Add(Me.TextBox3)

        Me.items = textBoxes 'IEnumerable(Of ) への代入は OK
      End Sub
    End Class


    上記の処理が認められているのは、List(Of T) の時とは違って「入力」ができないためです。
    たとえば、List(Of Control) だと行えていた下記の処理は、IEnumerable(Of Control) だと行えません。
      Me.items(0) = Me.Button1


    IEnumerable(Of T) インターフェイスでは、型パラメーターで指定された
    T 型もしくは T を継承した型を、「出力方向だけ」にしか使用しない仕様です。

    そこでこのように、
     『指定された型パラメーターが、出力(戻り値、ReadOnly Property)にしか使われない』
    ことを明確に伝えられるよう、VB2010 からは Out キーワードをつけて宣言できるようになりました。

    > Public Interface IEnumerable(Of Out T)


    上記を踏まえて、先ほどの共変性と反変性の件と In / Out キーワードがどう関わってくるかを見てみます。


    '=== 「In」なので「入力」にしか使われていない
    Public Interface ISample1(Of In T As Control)
      'この型パラメータ T では In によって『共変性』が保証されており、
      ' T 型は常に「広い型から狭い型へ変換するだけ」の実装になっている
      Sub Test(ByVal x As T)
      WriteOnly Property Prop As T
      'たとえば Of Control で実装された場合に、上記メンバーに対して
      'Label インスタンスや Form インスタンスを「入力」したとしても、何の問題も無い
    End Interface


    '=== 「Out」なので「出力」にしか使われていない
    Public Interface ISample2(Of Out T As Control)
      'この型パラメータ T では Out によって『反変性』が保証されており、
      ' T 型は常に「狭い型から広い型へ変換するだけ」の実装になっている
      Function Test() As T
      ReadOnly Property Prop As T
      'たとえば Of Control の場合に、上記メンバーの戻り値から
      'Label インスタンスや Form インスタンスが「出力」されてきたとしても、何の問題も無い
    End Interface


    '=== 双変の場合(つまり共変と反変の両方がありうる場合)は
    '=== In も Out も付与できない(付与するとコンパイルエラー)
    Public Interface ISample3(Of T As Control)
      Sub Test(ByRef x As T)
    End Interface
    Public Interface ISample4(Of T As Control)
      Property Prop As T
    End Interface
違反を報告
引用返信
■34413 / ResNo.3)  Re[3]: 共変性と反変性ってこういうこと?
□投稿者/ VBはじめました 一般人(26回)-(2019/12/06(Fri) 23:46:38)
  • アイコン魔界様いつもすみません。

    >改行無い 苦行じゃない?
    これについては、私の方が、ビックリしました。
    当然、自動で改行されるものとおもっていました。

    >その説明 C# のじゃない?
    まさしく、その通りかもしれません。
    VBでググると情報が少なく、レベルの低い私は、いまだに、.NETにおいては、VBとC#は書き方が違うだけでイコールである。の範疇を脱することが出来ていません。よって、C#との違いを理解しないまま、C#の記事をも参考にしています。そのせいもあり、余計にこんがらがっており、質問させて頂きました。
    しかし、見る人が見れば、説明が支離滅裂なのにも関わらず、参考にした文献の言語も判別でいるのにはビックリしました。

    >「広い型」や「狭い型」がDouble と Integer などの関係性を示しているのではありません。

    まさしく、そこがポイントです。ググるとString型、Objecto型。継承の関係。デリゲートとインターフェース。こんがらがるばかりです。

    Out/Inキーワードについては、Function/Actionの関係でなんとなく解った気でいますが、本質は分かっていないんだと感じています。

    VB,.NET Fraeworkのバージョンによってヘルプが変わっていることは、言われてみれば当然なことですが、それを調べられるように環境を整えているのにもビックリしました。

    >共変性と反変性の説明のためのサンプルなのだとしたら、
    どの部分が共変性で、
    投稿した後に、私も感じました。単に、IEnumerableが使えるよってサンプルになっていることを・・
    やはり、FunctionとActionで分けて考えるべきでした。

    Public Class Form1
      Private items As List(Of Control)

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim textBoxes As New List(Of TextBox)
        textBoxes.Add(Me.TextBox1)
        textBoxes.Add(Me.TextBox2)
        textBoxes.Add(Me.TextBox3)

        Me.items = textBoxes 'コンパイルエラー
      End Sub
    End Class

    を、コピペしてみると、VisualStudioにIEnumerableを使うことを考えろと怒られました。
    ただ、魔界さんの解説がなかったら、なんで?ここで?IEnumerableなの?
    って、疑問で、こんどは、IEnumerableでググって・・・・
    すると・・次のキーワードが出てきて、また、ググって・・・・
    同じところを、グルグル回って進みません。

    一つの解説書を順に・・とも思うのですが、頭が悪い分、理解できない部分があると、ググって・・・

    当座の最終目的は、ForEach文で、検索、抽出部分をLINQで書いて簡素にしようって
    ことなのですが、山が高くて 苦労しています。

    なんだか?魔界さんに個人レッスン料払わないとだめかな?って感じています。
    教えて頂いたおかげで、なんだか、気力が湧いてきました。
    なんとか、年内には、LINQを使えるようになれたらな?って考えています。

    もうすぐ、.NET Frameworkの時代が終わって、NET5になるって記事を読んだので
    この際、Framework4の基礎的な部分だけでも・・・と思っていますが
    同期、非同期、Yield、など、エベレスト級の山がそびえているので、どこまで
    いけるやら・・・

    少し、愚痴りましたが、教えて頂いたことは、無駄にすること無い様に熟読させて
    頂いて、なんとか習得に繋げたいと考えています。

    いつも、いつも有難うございます。




違反を報告
引用返信
■34414 / ResNo.4)  Re[4]: 共変性と反変性ってこういうこと?
□投稿者/ VBはじめました 一般人(27回)-(2019/12/06(Fri) 23:47:11)
  • アイコン解決忘れ
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]



■記事リスト / ▲上のスレッド
■34379 / 親記事)  プロセスからウインドウを取得
□投稿者/ /400 一般人(1回)-(2019/11/11(Mon) 23:26:51)
  • アイコン環境/言語:[vb.net2005] 
    分類:[.NET] 

    vb.net2005 winformです
    ウインドウの一覧を先に取得してそれをプロセスで束ねてく方法は分かるのですが、
    それだと時間がかかるのでプロセス一覧を先に取得して画面のあるものだけ
    ウインドウを取得したいのです
    ただそれだと一つのプロセスから複数のウインドウを表示しているような場合取得
    できません
    どのようにすればよいのでしょう

違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34381 / ResNo.1)  Re[1]: プロセスからウインドウを取得
□投稿者/ 魔界の仮面弁士 大御所(1254回)-(2019/11/12(Tue) 10:28:08)
  • アイコンNo34379に返信(/400さんの記事)
    > ウインドウの一覧を先に取得して
    ここでいうウィンドウとは、何を指していますか?

    トップレベルウィンドウ(EnumWindows)だけではなく、
    TextBox や Button、あるいは ComboBox のエディタ部とリスト部などといった、
    hWnd を持つオブジェクトすべてを指しているのでしょうか? (EnumChildWindows)


    > それをプロセスで束ねてく方法は分かるのですが、

    別案を求めるのであれば、そもそも現状、どうやって取得しているのかを
    示してもらった方が答えやすいです。たとえばこういった処理を行っているのでしょうか。
    https://www.atmarkit.co.jp/fdotnet/dotnettips/233enumwin/enumwin.html

    あるいは EnumWindows のコールバック結果を GetWindowThreadProcessId で判定しているとか?
    https://smdn.jp/programming/tips/enumwindows/



    > それだと時間がかかるので
    まず、列挙の目的は何でしょうか?
    そして現状の方法だとどの程度かかっていて、それをどの程度にまで短縮させたいのでしょうか?
    また、現状の処理で特に時間がかかっているのは、どの部分でしょうか?


    > ただそれだと一つのプロセスから複数のウインドウを表示しているような場合取得
    > できません
    どういう処理を書いているか分かりませんが、単一ウィンドウを取得する方法の場合、
    十分に短い時間で処理できているのでしょうか?

    ちなみに Process.MainWinowHandle プロパティの実装は、
    EnumWindows + GetWindowThreadProcessId で判定するという手法で実装されています。
    加えて、それがメインウィンドウであるかの判定のために、
    GetWindow(HWND, GW_OWNER) が IntPtr.Zero かつ IsWindowVisible(HWND) が True で
    あるかどうかも検査しています。アンマネージコードでも構わなければ、上記手法で
    最初に見つけたところで列挙を終えず、そのままコールバックを継続すればよいかと。
違反を報告
引用返信
■34390 / ResNo.2)  Re[2]: プロセスからウインドウを取得
□投稿者/ /400 一般人(4回)-(2019/11/14(Thu) 18:15:24)
  • アイコンNo34381に返信(魔界の仮面弁士さんの記事)

    レスありがとうございます

    > ここでいうウィンドウとは、何を指していますか?

    > まず、列挙の目的は何でしょうか?

    簡易的なタスクスイッチャーみたいなものを作ろうとしていて、例えばWZEditorというエディタがあるのですがタスクマネージャーのプロセスにはWZ_Main.exeだけがあり、アプリケーションの方には読ませたファイルの数だけ実際に見えているウインドウが並んでいるわけです("Hoge1.txt - WZ EDITOR" "Hoge2.txt - WZ EDITOR"みたいに)
    ところがプロセスのメインウインドウだとそのうちの1つしか取得できませんよね
    でプロセスが表示している全てのウインドウが取得出来ないかなと

    プロセスの取得はManagementObjectCollectionからプロセスIDを取得してそのプロセスIDからGetProcessByIdでプロセスを取得しています
    で、プロセスのMainWindowHandleがIntPtr.Zeroで無いものを処理しています

違反を報告
引用返信
■34391 / ResNo.3)  Re[3]: プロセスからウインドウを取得
□投稿者/ 魔界の仮面弁士 大御所(1259回)-(2019/11/14(Thu) 20:31:01)
  • アイコンNo34390に返信(/400さんの記事)
    > プロセスの取得はManagementObjectCollectionからプロセスIDを取得して
    WMI からのアプローチなのですね。
    使っているのは、root\CIMV2 名前空間の Win32_Process クラスあたりでしょうか。


    > そのプロセスIDからGetProcessByIdでプロセスを取得しています
    新しいプロセスの起動等を検知するために、__InstanceCreationEvent / __InstanceDeletionEvent を
    仕掛けているといった事情があるのなら、WMI を使う価値はあるかもしれませんが、
    単に Process クラスのインスタンスを得ることが目的なのだとしたら、プロセスの列挙は
    WMI を経由させずとも、最初から Process.GetProcesses を使った方が手っ取り早い気がします。


    ただ、最終的に必要なのはウィンドウハンドル(あるいはそのタイトル?)のようなので、その場合、
    前回の回答で述べた EnumWindows + GetWindowThreadProcessId で探すことになりそうです。
    ここの Tips 集にある [プロセス]>[ウィンドウのタイトルからプロセスを探す] でも使われていますね。


    とはいっても、最初の質問で
    >>> ウインドウの一覧を先に取得してそれをプロセスで束ねてく方法は分かるのですが、
    との事ですので、恐らくその方法は既にご存知なのかと思います。

    ウィンドウ数が膨大で列挙が遅いというのであれば、列挙完了まで待たせるのではなく、
    探索はワーカースレッドに任せ、対象プロセスのウィンドウだったものが
    逐次通知されてくるようにするのはどうでしょうか。
違反を報告
引用返信
■34392 / ResNo.4)  Re[4]: プロセスからウインドウを取得
□投稿者/ 魔界の仮面弁士 大御所(1260回)-(2019/11/14(Thu) 21:47:22)
  • アイコン
    No34391に追記(魔界の仮面弁士の記事)
    >>>> ウインドウの一覧を先に取得してそれをプロセスで束ねてく方法は
    >>>> 分かるのですが、それだと時間がかかるので
    > ウィンドウ数が膨大で列挙が遅いというのであれば、
    
    手元の VB2005 で試してみましたが、数百ミリ秒以内に列挙が完了しており、
    言うほど時間がかかるようには思えませんでした。
    
    比較のため、そちらで実装したコードを見せて頂けないでしょうか?
    
    
    Option Strict On
    Imports System.Runtime.InteropServices
    Imports System.Text
    Imports System.ComponentModel
    Public Class Form1
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim dt As New DataTable()
            dt.Columns.Add("PID", GetType(Integer))
            dt.Columns.Add("ProcessName", GetType(String))
            dt.Columns.Add("HWND", GetType(IntPtr))
            dt.Columns.Add("Title", GetType(String))
            EnumWindows(AddressOf EnumWindowCallBack, dt)
            Me.DataGridView1.DataSource = dt
            Me.DataGridView1.Columns("PID").DefaultCellStyle.Format = "X8"
            Me.DataGridView1.Columns("HWND").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
        End Sub
    
        Private Function EnumWindowCallBack(ByVal hWnd As IntPtr, ByVal lparam As DataTable) As Boolean
            If GetWindow(hWnd) = IntPtr.Zero AndAlso IsWindowVisible(hWnd) Then
                Dim processId As Integer
                GetWindowThreadProcessId(hWnd, processId)
                Dim procName As String = ""
                Try
                    'procName = Process.GetProcessById(processId).ProcessName
                Catch
                End Try
                Dim Title As String = ""
                'Dim textLen As Integer = GetWindowTextLength(hWnd)
                'If textLen > 0 Then
                '    Dim tsb As New StringBuilder(textLen + 1)
                '    GetWindowText(hWnd, tsb, tsb.Capacity)
                '    Title = tsb.ToString(0, textLen)
                'End If
                lparam.Rows.Add(processId, procName, hWnd, Title)
            End If
            Return True
        End Function
        <DllImport("user32.dll", CharSet:=CharSet.Unicode, EntryPoint:="GetWindowTextW", SetLastError:=True)> _
        Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
        End Function
        <DllImport("user32.dll", CharSet:=CharSet.Unicode, EntryPoint:="GetWindowTextLengthW", SetLastError:=True)> _
        Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
        End Function
        Private Delegate Function EnumWindowsDelegate(ByVal hWnd As IntPtr, ByVal lparam As DataTable) As Boolean
        <DllImport("user32.dll")> _
        Private Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsDelegate, ByVal lparam As DataTable) As Boolean
        End Function
        <DllImport("user32.dll", SetLastError:=True)> _
        Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
        End Function
        Private Const GW_OWNER As Integer = 4
        <DllImport("user32.dll")> _
        Private Shared Function GetWindow(ByVal hWnd As IntPtr, Optional ByVal uCmd As Integer = GW_OWNER) As IntPtr
        End Function
        <DllImport("user32.dll")> _
        Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
        End Function
    End Class

違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]






Mode/  Pass/


- Child Tree -