VisualBasic.PowerPacks.ShapeContainer について への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/9/3 22:46:23
> Me.ShapeContainer1.Shapes[0]
> と入力すると、
> 「CS0020 角かっこ [] 付きインデックスを 'type' 型の式に適用することはできません」
えぇと…??? 質問内容に混乱が見られるような。
> VC# で同様のことができるか教えて下さい。
Microsoft.VisualBasic.PowerPacks.ShapeCollection クラスはインデクサを有していません。
『インデクサ』ではなく、『引数付きプロパティ』として実装されています。
https://docs.microsoft.com/en-us/previous-versions/bb917992
Visual Basic 側の文法で言えば、
見ての通り、IList が実装されていますので、引数付きプロパティをサポートしていない C# であっても、
dynamic shape = ((System.Collections.IList)this.shapeContainer1.Shapes)[0];
のように、IList を通じてアクセスすることが可能です。
あるいは、動的言語サポートを通じて、
dynamic shapes = this.shapeContainer1.Shapes;
dynamic shape = shapes[0];
shapes[0] = shape; // 使わないとは思うけれど、代入操作も可能
のように書くこともできます。
そのほか、引数付きプロパティを持つクラスが C# 側に引き渡された場合、
getter / setter のメソッドを通じてアクセスすることができます。たとえば、
'Dim shape As Object = Me.ShapeContainer1.Shapes(0)
Dim shape As Object = Me.ShapeContainer1.Shapes.Item(0)
Me.ShapeContainer1.Shapes.Item(0) = shape
に相当するコードを C# では
dynamic shape = this.shapeContainer1.Shapes.get_Item(0);
this.shapeContainer1.Shapes.set_Item(0, shape);
のように書けます。
https://ufcpp.net/blog/2016/12/tipsimplicitmembers/
ちなみに Visual Basic 側でも、サポートされていない演算子のオーバーロードを呼び出すために、
このような代替名でのアクセスが必要になるケースがあるのですが…それはまた別のお話。
> と入力すると、
> 「CS0020 角かっこ [] 付きインデックスを 'type' 型の式に適用することはできません」
えぇと…??? 質問内容に混乱が見られるような。
◾ CS0020 は確かに C# コンパイラのエラーコードですが、その意味は
「定数 0 による除算」だったはずです。 CS0021 の間違いではありませんか?
◾ C# に Me というキーワードはありません。this の間違いではありませんか?
◽ Visual Basicの命名ルールが何故か引き継がれているようですね。
Visual Basicで作られたデザイン情報を、たとえばクリップボードを使うなどして
C# 側に移植したということでしょうか? Name プロパティの初期設定は
PascalCase 表記な ShapeContainer1 が Visual Basic デザイナによるもので
camelCase 表記な shapeContainer1 が C# デザイナのものとなるはずなので…。
「定数 0 による除算」だったはずです。 CS0021 の間違いではありませんか?
◾ C# に Me というキーワードはありません。this の間違いではありませんか?
◽ Visual Basicの命名ルールが何故か引き継がれているようですね。
Visual Basicで作られたデザイン情報を、たとえばクリップボードを使うなどして
C# 側に移植したということでしょうか? Name プロパティの初期設定は
PascalCase 表記な ShapeContainer1 が Visual Basic デザイナによるもので
camelCase 表記な shapeContainer1 が C# デザイナのものとなるはずなので…。
> VC# で同様のことができるか教えて下さい。
Microsoft.VisualBasic.PowerPacks.ShapeCollection クラスはインデクサを有していません。
『インデクサ』ではなく、『引数付きプロパティ』として実装されています。
https://docs.microsoft.com/en-us/previous-versions/bb917992
Visual Basic 側の文法で言えば、
Default Public Property Item(index As Integer) As Object
は持ち合わせていない、ということです。ただしPublic Property Item(index As Integer) As Object Implements IList.Item
であれば実装されています。見ての通り、IList が実装されていますので、引数付きプロパティをサポートしていない C# であっても、
dynamic shape = ((System.Collections.IList)this.shapeContainer1.Shapes)[0];
のように、IList を通じてアクセスすることが可能です。
あるいは、動的言語サポートを通じて、
dynamic shapes = this.shapeContainer1.Shapes;
dynamic shape = shapes[0];
shapes[0] = shape; // 使わないとは思うけれど、代入操作も可能
のように書くこともできます。
そのほか、引数付きプロパティを持つクラスが C# 側に引き渡された場合、
getter / setter のメソッドを通じてアクセスすることができます。たとえば、
'Dim shape As Object = Me.ShapeContainer1.Shapes(0)
Dim shape As Object = Me.ShapeContainer1.Shapes.Item(0)
Me.ShapeContainer1.Shapes.Item(0) = shape
に相当するコードを C# では
dynamic shape = this.shapeContainer1.Shapes.get_Item(0);
this.shapeContainer1.Shapes.set_Item(0, shape);
のように書けます。
https://ufcpp.net/blog/2016/12/tipsimplicitmembers/
ちなみに Visual Basic 側でも、サポートされていない演算子のオーバーロードを呼び出すために、
このような代替名でのアクセスが必要になるケースがあるのですが…それはまた別のお話。
投稿者 VB+VC# Beginner  (社会人)
投稿日時
2020/9/3 20:43:41
Microsoft.VisualBasic.PowerPacks.ShapeContainer についてお尋ねします。
Windows Form に Lineshape を描画するために、VisualBasic.PowerPacks をインストールしました。
Lineshape を複数個描画すると、VB では、Designer.vb の中に、
Me.ShapeContainer1.Shapes.AddRange(New Microsoft.VisualBasic.PowerPacks.Shape() {
Me.LineShape_00, Me.LineShape_01, ... })
の記述が見つかったので、Lineshape のプロパティーを
For i=0 to 59
Me.ShapeContainer1.Shapes(i).X2 = ??
Next
のように、For ~Next で設定することができました。
その後、VisualBasic.PowerPacks を VC# でも利用できることを知り、同じことができるか試してみました。
Designer.cs の中に、
this.shapeContainer1.Shapes.AddRange(new Microsoft.VisualBasic.PowerPacks.Shape[] {
this.lineShape00, this.lineShape01, ... });
の記述が見つかったので、
Me.ShapeContainer1.Shapes[0]
と入力すると、
「CS0020 角かっこ [] 付きインデックスを 'type' 型の式に適用することはできません」
のエラーが出ます。
ShapeContainer1.Shapes がたくさんあると、「ShapeContainer1.Shapes(i).」の書き方ができると
非常に便利です。
VC# で同様のことができるか教えて下さい。
Windows Form に Lineshape を描画するために、VisualBasic.PowerPacks をインストールしました。
Lineshape を複数個描画すると、VB では、Designer.vb の中に、
Me.ShapeContainer1.Shapes.AddRange(New Microsoft.VisualBasic.PowerPacks.Shape() {
Me.LineShape_00, Me.LineShape_01, ... })
の記述が見つかったので、Lineshape のプロパティーを
For i=0 to 59
Me.ShapeContainer1.Shapes(i).X2 = ??
Next
のように、For ~Next で設定することができました。
その後、VisualBasic.PowerPacks を VC# でも利用できることを知り、同じことができるか試してみました。
Designer.cs の中に、
this.shapeContainer1.Shapes.AddRange(new Microsoft.VisualBasic.PowerPacks.Shape[] {
this.lineShape00, this.lineShape01, ... });
の記述が見つかったので、
Me.ShapeContainer1.Shapes[0]
と入力すると、
「CS0020 角かっこ [] 付きインデックスを 'type' 型の式に適用することはできません」
のエラーが出ます。
ShapeContainer1.Shapes がたくさんあると、「ShapeContainer1.Shapes(i).」の書き方ができると
非常に便利です。
VC# で同様のことができるか教えて下さい。
早速ご回答ありがとうございました。
おっしゃる通り、
「this.shapeContainer1.Shapes[0].」
「CS0021」
の間違いでした。
ご回答の方法は明日以降に試してみます。
とりあえず「方法はある」ことがわかり、安心しました。