C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: VBでOptionStrictOnで匿名クラスを使いたい!


(過去ログ 140 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■82124 / inTopicNo.1)  VBでOptionStrictOnで匿名クラスを使いたい!
  
□投稿者/ yapii (4回)-(2016/12/13(Tue) 10:54:20)

分類:[.NET 全般] 

VBでOptionStrictOnで匿名クラスを使いたい!です。

何か方法はないでしょうか。



引用返信 編集キー/
■82125 / inTopicNo.2)  Re[1]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ Hongliang (476回)-(2016/12/13(Tue) 11:05:10)
使えますよ(VB2008以降であれば)。

もしかすると想定されているのはVB用語としての匿名型ではない何かかも知れません。
具体的にこういう風に書きたいという擬似コードを挙げられてみてはいかがでしょうか。
引用返信 編集キー/
■82126 / inTopicNo.3)  Re[1]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ 魔界の仮面弁士 (1010回)-(2016/12/13(Tue) 11:12:04)
No82124 (yapii さん) に返信
> VBでOptionStrictOnで匿名クラスを使いたい!です。
> 何か方法はないでしょうか。

匿名クラス…とは何のことを指していますか?
匿名型や ExpandoObject の事でしょうか?


Dim anonymousType As New With {.X = 1, .Y = 2, Key .Z = 3}
anonymousType.X += anonymousType.Y
MsgBox(anonymousType.Z)

Dim exp As New System.Dynamic.ExpandoObject()
Dim a As Object = exp
Dim b As IDictionary(Of String, Object) = exp

CallByName(a, "Test1", CallType.Set, 123)
MsgBox(b("Test1"))

b("Test2") = 465
MsgBox(CallByName(a, "Test2", CallType.Get))
引用返信 編集キー/
■82127 / inTopicNo.4)  Re[2]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ Hongliang (477回)-(2016/12/13(Tue) 11:12:40)
あ、Option InferをOffにしていると、Asが必須だが型名を記述できないという話でしょうか。
Option Infer Onであれば、型が明らかに推論できる部分についてはOption Strict OnであってもAsを記述しなくてよくなります。

Option Infer On
Option Strict On

' aの型は明らかにIEnumerable(Of 匿名型)なのでStrict OnであってもAs不要
Dim a = Enumerable.Range(0, 10).Select(Function (i) New With { Value = i })

引用返信 編集キー/
■82128 / inTopicNo.5)  Re[3]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ shu (948回)-(2016/12/13(Tue) 11:45:35)
Sub,Function内では可能です。

外の話でしょうか?
=> Option関係なくObject型になるので型情報から
プロパティメソッドにアクセスする必要があります。

サンプル

Public Class Form1

    Private a As Object = New With {.a = 1, .b = 2}

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim tpA = a.GetType()
        Dim a_a = CInt(tpA.GetProperty("a").GetValue(a, Nothing))
        Dim a_b = CInt(tpA.GetProperty("b").GetValue(a, Nothing))
        Console.WriteLine("{0} {1}", a_a, a_b)

        Dim b = New With {.a = 3, .b = 4}
        Console.WriteLine("{0} {1}", b.a, b.b)
    End Sub
End Class

引用返信 編集キー/
■82129 / inTopicNo.6)  Re[3]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ yapii (5回)-(2016/12/13(Tue) 12:00:11)
後だしですいません。
VB2013 
Fw4.0 
VB
Option Strinct On
Option Infer On

Dapperを使用しようと試しています。

Dappeprが匿名クラスを返すのですが、その匿名クラスのプロパティを使用するところで
OptionStrictOnでは遅延バインディングをしようできませんとコンパイルエラーになります

    Public Class MyUser
            Public Property Code As Integer
            Public Property Name As String
        End Class

        Public Shared Function CreateUser(id As String) As MyUser

            Dim sql As String = "SELECT ExCode, ExName FROM MYTABLE FROM ID = :id"
            Dim prms = New With {.id = 1}

            Dim user As MyUser = Nothing
            Using cnn As DbConnection = dbFactory.CreateConnection("接続文字列")
                cnn.Open()
                Try

                    Dim val = cnn.QuerySingleOrDefault(sql, prms)
                    If val IsNot Nothing Then
                        user = New MyUser
                        user.Code = funcGotyaGotya(val.ExCode) <−−ここでOptionStrictOnでは遅延バインディングをしようできませんとコンパイルエラー
                        user.Name = funcKoneKone(val.ExName) <−−ここも
                    End If

                Finally
                    cnn.Close()
                End Try
            End Using
            Return user
        End Function

引用返信 編集キー/
■82130 / inTopicNo.7)  Re[4]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ Hongliang (478回)-(2016/12/13(Tue) 12:57:03)
DapperのQuery系メソッドが返すオブジェクトは、「匿名型」ではなく「dynamic型」です。
VBではdynamic型はOption Strict Offで扱うしかないみたいですね。
インスタンス単位で扱えないのは面倒だな…。
引用返信 編集キー/
■82135 / inTopicNo.8)  Re[5]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ yapii (6回)-(2016/12/13(Tue) 14:54:09)
ありがとうございました。
Dapperは諦めます(T T)

Option Strict On で Dynamic型をあつかえる日が来るのでしょうか・・・

引用返信 編集キー/
■82143 / inTopicNo.9)  Re[6]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ shu (949回)-(2016/12/13(Tue) 16:28:19)
No82135 (yapii さん) に返信
> ありがとうございました。
> Dapperは諦めます(T T)
>
> Option Strict On で Dynamic型をあつかえる日が来るのでしょうか・・・
>
VBのOption Strict Off とC#のDynamic型はほぼ同じことなので
それはC#でDynamic型を使わないと言っているのとほぼ同じことなのです。



MSDN Option Strict の解説より
---
Option Strict On または Option Strict がファイル内にあるとき、次の条件によってコンパイル時のエラーが発生します。
暗黙の縮小変換
遅延バインディング
Object 型になる暗黙的な型指定
----

なので


CallByNameとかType.GetProperty経由でのアクセスをする必要があります。

引用返信 編集キー/
■82150 / inTopicNo.10)  Re[6]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ 魔界の仮面弁士 (1015回)-(2016/12/13(Tue) 18:52:16)
No82135 (yapii さん) に返信
> Option Strict On で Dynamic型をあつかえる日が来るのでしょうか・・・

操作用の拡張メソッドを用意しておいては如何でしょう。
MsgBox( dynObj.Test ) の代わりに
MsgBox( dynObj.GetProp("Test") ) と書く感じで。


Option Strict On
Imports System.Dynamic
Imports System.Runtime.CompilerServices
Friend Module DynamicExtensions
  <Extension> Friend Sub SetProp(Of T)(this As DynamicObject, memberName As String, newValue As T)
    CallByName(this, memberName, CallType.Set, newValue)
  End Sub

  <Extension> Friend Function GetProp(this As DynamicObject, memberName As String) As Object
    Return CallByName(this, memberName, CallType.Get)
  End Function

  <Extension> Friend Function GetPropT(Of T)(this As DynamicObject, memberName As String) As T
    Return DirectCast(CallByName(this, memberName, CallType.Get), T)
  End Function
End Module
引用返信 編集キー/
■82162 / inTopicNo.11)  Re[7]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ yapii (7回)-(2016/12/14(Wed) 10:04:50)
shuさま

>VBのOption Strict Off とC#のDynamic型はほぼ同じことなので
>それはC#でDynamic型を使わないと言っているのとほぼ同じことなのです。


例えばC#であれば以下のように書けます。
「user.Code = "123"」の部分は暗黙的型変換でコンパイルエラーになります。

OptionStrictOnのVBではかけません。
「user.Code = "123"」の部分は暗黙的型変換でコンパイルエラーになります。

Option Strict Offにすれば書けます。
「user.Code = "123"」の部分もコンパイルエラーになりません。(これは困ります)

C#のように暗黙的型変換はエラーになりつつ、Dynamicでは許してほしいのです。
====C#============================================================================
public class MyUser
{
    public int Code { get; set; }
    public string Name { get; set; }
}

private void Test()
{
    dynamic obj = CreateDynamicObject();
    MyUser user = new MyUser();
    user.Code = Convert.ToInt32(obj.Code.Replace("A", ""));
    user.Name = obj.Name.ToString();

    //user.Code = "123"; <--C#ではコンパイルエラー
}

private dynamic CreateDynamicObject()
{
    return new { Code = "A123", Name = 123 };
}
==================================================================================
魔界の仮面弁士さま

>操作用の拡張メソッドを用意しておいては如何でしょう。
>MsgBox( dynObj.Test ) の代わりに
>MsgBox( dynObj.GetProp("Test") ) と書く感じで。

ありがとうございます。
vbではdynamic型はobject型で扱う。→Object型は拡張メソッドが作れない。と思っていました。
トライしてみます。

引用返信 編集キー/
■82164 / inTopicNo.12)  Re[8]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ 魔界の仮面弁士 (1019回)-(2016/12/14(Wed) 11:22:04)
No82127 (Hongliang さん) に返信
> Dim a = Enumerable.Range(0, 10).Select(Function (i) New With { Value = i })

『New With { Value = i }』だとコンパイルエラーなので
『New With { Key .Value = i }』ですね。(Key を付けるかどうかは任意)



No82162 (yapii さん) に返信
> OptionStrictOnのVBではかけません。
> Option Strict Offにすれば書けます。

(On の時にも空白を入れて表記して欲しい、と思ってみたり)


> C#のように暗黙的型変換はエラーになりつつ、Dynamicでは許してほしいのです。

Dynamic というのは C# の dynamic の事でしょうか。

C# で言うところの dynamic が欲しいという意見には同意です。(^^;
型名が dynamic だと VB っぽくないので、Dynamic とか Variant あたりで。

あるいはせめて、Option Strict を、ファイルスコープではなく
ブロックレベルのスコープで指定できる仕組みとか。
イメージ的にはこんな感じで。

 Dim obj = CreateDynamicObject()
 Dim user As New MyUser()
 Strict Off
  user.Code = Convert.ToInt32(obj.Code.Replace("A", ""))
  user.Name = obj.Name.ToString()
 End Strict


> vbではdynamic型はobject型で扱う。
大文字小文字の違いに注意。

object 型 → C# のプリミティブ型
Object 型 → VB のプリミティブ型 あるいは System.Object クラス


Dapper の Query 系拡張メソッドが返すオブジェクトは、
実質的には Dapper.SqlMapper+DapperRow のコレクションらしいですが、
その DapperRow は、System.Dynamic.ExpandoObject と同様に
IDictionary(Of String, Object) を実装していますので、
No82126 の手順をとることで、Option Strict On でもアクセス可能です。


Dim q = cnn.Query(sql, prms)
For Each row As IDictionary(Of String, Object) In q
 MsgBox(row(fieldName))
Next
引用返信 編集キー/
■82167 / inTopicNo.13)  Re[8]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ shu (950回)-(2016/12/14(Wed) 12:44:08)
No82162 (yapii さん) に返信

試してはいませんがプロジェクトのコンパイルオプションで
Option Strict Off
『暗黙的な変換』 => 通知を警告 or エラーにする。
ではどうでしょう?
プロジェクトレベルにはなりますがかなり希望に近い動作になると思われます。
引用返信 編集キー/
■82171 / inTopicNo.14)  Re[9]: VBでOptionStrictOnで匿名クラスを使いたい!
□投稿者/ yapii (8回)-(2016/12/14(Wed) 14:43:05)
shuさま

>Option Strict Off
>『暗黙的な変換』 => 通知を警告 or エラーにする。

ありがとうございます。
試してみます!!


ありがとうございます。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -