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

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

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

Re[8]: スーパクラスまたはそのサブクラスを格納するコレクション


(過去ログ 78 を表示中)

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

■46205 / inTopicNo.1)  スーパクラスまたはそのサブクラスを格納するコレクション
  
□投稿者/ yan (6回)-(2010/01/28(Thu) 09:45:19)

分類:[.NET 全般] 

VS2008 VB 

あるメソッドがあり、引数にスーパクラスまたはそのサブクラスを格納するコレクションを指定したいのですが、
方法がわかりません。

javaでは
ArrayList<Parent> ary1 = new ArrayList<Super>();
meth(ary1);

ArrayList<Child> ary2 = new ArrayList<Child>();
meth(ary2);

public void meth(ArrayList<? extends Parent> ary){}


といったことができたと思いますが、.Net(VB)ではできるでしょうか?

よろしくお願いいたします。
引用返信 編集キー/
■46207 / inTopicNo.2)  Re[1]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ επιστημη (2412回)-(2010/01/28(Thu) 10:11:06)
επιστημη さんの Web サイト
↓たとえばこんなの?

Imports System.Collections.Generic

Public Interface IHoge
  Sub Hoge()
End Interface

Public Class HogeInt : Implements IHoge
  Private value As Integer
  Public Sub New(n As Integer)
    value = n
  End Sub
  Public Sub Hoge() Implements IHoge.Hoge
    System.Console.WriteLine("Hoge:{0}", value)
  End Sub
End Class

Module Program

  '--- IHoge を実装する T を要素とするhogesの各要素に対し、
  '--- 片っ端からほげる。
  Sub AllHoge(Of T As IHoge)(hoges As IEnumerable(Of T))
    For Each item As IHoge In hoges
      item.Hoge()
    Next
  End Sub

  Sub Main()
    Dim hoges As New List(Of IHoge)
    hoges.Add(New HogeInt(123))
    hoges.Add(New HogeInt(456))
    hoges.Add(New HogeInt(789))
    AllHoge(hoges)
  End Sub
End Module


引用返信 編集キー/
■46212 / inTopicNo.3)  Re[2]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ yan (8回)-(2010/01/28(Thu) 11:35:59)
επιστημη さん
返答ありがとうございます。

すみません。
私の質問がとても悪かったです。
(※先ほどの質問では、教えて頂いたプログラムでできました。ありがとうございます。)


具体的にやりたい事を書きます。申し訳ありません。

Parentクラスを継承したChildクラスに
Childクラスを格納するListコレクションがPublic Shared ReadOnlyで定義されています。

このListコレクションを親クラスであるParentクラスで取得したいのです。
以下のようなコードを書いたのですが、コンパイルエラーになってしまいます。
GetListメソッドの戻り値がParentまたはそのサブクラスと指定できれば、解決できるかと思い先の質問をしました。

Public Class Child : Inherits Parent
  Public Shared ReadOnly List As List(Of Child)

  Protected Overrides Function GetList() As System.Collections.Generic.List(Of Parent)
    Return List 'コンパイルエラー
  End Function
End Class

Public MustInherit Class Parent

  Public Sub TestMethod()
    'ChildクラスのListを取得したい
    Dim lst As List(Of Parent) = GetList()
  End Sub

  Protected MustOverride Function GetList() As List(Of Parent)

End Class


現状はParentクラスのGetListメソッドの戻り値をIListにすることで、ChildクラスのListを取得できています。
Public Class Child : Inherits Parent

  Public Shared ReadOnly List As List(Of Child)


  Public Overloads Overrides Function GetList() As IList
    Return List
  End Function
End Class

Public MustInherit Class Parent

  Public Sub TestMethod()
    'ChildクラスのListを取得したい
    Dim lst As IList = GetList()
    For Each obj As Object In lst
      Dim p As Parent = CType(obj, Parent)
    Next
  End Sub

  Public MustOverride Function GetList() As IList

End Class

引用返信 編集キー/
■46215 / inTopicNo.4)  Re[3]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ επιστημη (2414回)-(2010/01/28(Thu) 12:01:11)
επιστημη さんの Web サイト
んー...C#だと yield 使って"似たこと"やらせられるんですけどねー

using System.Collections.Generic;

public abstract class Parent {

  private int value;
  private void Hoge() {
    System.Console.WriteLine("Parent.Hoge {0}", value);
  }
  public Parent(int n) {
    value = n;
  }
  public void TestMethod() {
    List<Parent> parents = new List<Parent>(GetList());
    foreach ( Parent item in GetList() ) {
      item.Hoge();
    }
  }

  protected abstract IEnumerable<Parent> GetList();
}

public class Child : Parent {
  protected override IEnumerable<Parent> GetList() {
    foreach ( Parent child in Children ) {
      yield return child;
    }
  }
  public Child(int n) : base(n) { 
    Children.Add(this);
  }

  public static readonly List<Child> Children = new List<Child>();

}

class Program {
  public static void Main() {
    Parent p;
    p = new Child(123);
    p = new Child(456);
    p = new Child(789);
    p.TestMethod();
  }
}

引用返信 編集キー/
■46216 / inTopicNo.5)  Re[4]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ みきぬ (751回)-(2010/01/28(Thu) 12:06:37)
List(Of T).ConvertAll() を使うとか。
引用返信 編集キー/
■46219 / inTopicNo.6)  Re[5]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ επιστημη (2415回)-(2010/01/28(Thu) 12:19:20)
επιστημη さんの Web サイト
> List(Of T).ConvertAll() を使うとか。

List(Of Child) から List(Of Parent) を"生成する"んだったら
ConvertAll()でも、あるいは無骨にForEachくるくる回してもいいんだけど、
質問のキモは List(Of Child) を List(Of Parent) に"見せかける"ことができるか?

と解釈したのよね。
で、僕の答は"C#なら(yield使って) List<Child> を IEnumarable<Parent> に偽装(?)できる"、と。

引用返信 編集キー/
■46221 / inTopicNo.7)  Re[6]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ みきぬ (752回)-(2010/01/28(Thu) 12:24:54)
2010/01/28(Thu) 12:26:11 編集(投稿者)

No46219 (επιστημη さん) に返信
>>List(Of T).ConvertAll() を使うとか。
>
> List(Of Child) から List(Of Parent) を"生成する"んだったら
> ConvertAll()でも、あるいは無骨にForEachくるくる回してもいいんだけど、
> 質問のキモは List(Of Child) を List(Of Parent) に"見せかける"ことができるか?
>
> と解釈したのよね。
> で、僕の答は"C#なら(yield使って) List<Child> を IEnumarable<Parent> に偽装(?)できる"、と。
>
なるほど。

それなら Linq を使って Cast(Of Parent)() だとどうかしら。
# 中でやってることは yield return と大してかわらんような気はするけど
引用返信 編集キー/
■46222 / inTopicNo.8)  Re[7]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ yan (9回)-(2010/01/28(Thu) 13:04:43)
επιστημη さん、みきぬさん
返答ありがとうございます。

Framework2.0では無理っぽいですね。
※Framework2.0が絶対条件ではありません。

VBにはyieldはありませんし・・・
Linqで試してみようと思います。

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


引用返信 編集キー/
■46223 / inTopicNo.9)  Re[8]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ επιστημη (2416回)-(2010/01/28(Thu) 13:14:30)
επιστημη さんの Web サイト
で、Childが
 Public Shared ReadOnly List As List(Of Parent)
を持つわけにはいかんのですか?

まぁ、いよいよとなれば 

Protected Overrides Function GetList() As System.Collections.Generic.List(Of Parent)
  Dim result As New List(Of Parent)して
  ForEachでくるくる回って
    Addして
  result 返せばいいんちゃいます?
  ' ガキが数千人いたらァレですけど
End Function

引用返信 編集キー/
■46224 / inTopicNo.10)  Re[8]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ みきぬ (753回)-(2010/01/28(Thu) 14:05:13)
No46222 (yan さん) に返信
> Framework2.0では無理っぽいですね。

つまりそれは、.NET Framerowk 2.0 でも使える ConvertAll() では要求を満たさない(επιστημηさんの解釈であっている)っていう風に理解してええんですかね。
引用返信 編集キー/
■46232 / inTopicNo.11)  Re[9]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ yan (10回)-(2010/01/28(Thu) 18:29:58)
>Public Shared ReadOnly List As List(Of Parent)を持つわけにはいかんのですか?
Dim c As Child =Ctype(List.Item(0),Child)と使う時にキャストしないといけないのでムリです。



> つまりそれは、.NET Framerowk 2.0 でも使える ConvertAll() では要求を満たさない(επιστημηさんの解釈であっている)っていう風に理解してええんですかね。
すいませんでした。ConvertAll() も試してみます。

ありがとうございました。
解決済み
引用返信 編集キー/
■46284 / inTopicNo.12)  Re[8]: スーパクラスまたはそのサブクラスを格納するコレクション
□投稿者/ επιστημη (2421回)-(2010/01/29(Fri) 12:00:48)
επιστημη さんの Web サイト
> VBにはyieldはありませんし・・・

足らぬ足らぬは工夫が足らぬ、と♪

Imports System.Collections.Generic

Public MustInherit Class Parent

    Private value As Integer
    Private Sub Hoge()
        System.Console.WriteLine("Parent.Hoge {0}", value)
    End Sub

    Public Sub New(ByVal n As Integer)
        value = n
    End Sub

    Public Sub TestMethod()
        Dim parents As New List(Of Parent)(GetList())
        For Each item As Parent In parents
            item.Hoge()
        Next
    End Sub

    Public MustOverride Function GetList() As IEnumerable(Of Parent)

End Class

Public Class Child : Inherits Parent

    Public Class Enumerable : Implements IEnumerable(Of Parent)
        Public Function GetEnumeratorGeneric() As IEnumerator(Of Parent) Implements IEnumerable(Of Parent).GetEnumerator
            Return New Enumerator(Children.GetEnumerator())
        End Function
        Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
            Return New Enumerator(Children.GetEnumerator())
        End Function
    End Class

    Public Class Enumerator : Implements IEnumerator(Of Parent)
        Private en_ As IEnumerator(Of Child)
        Public Sub New(ByVal en As IEnumerator(Of Child))
            en_ = en
        End Sub
        Public Sub Reset() Implements IEnumerator(Of Parent).Reset
            en_.Reset()
        End Sub
        Protected Sub Dispose() Implements IDisposable.Dispose
            ' nothing to do
        End Sub
        Public Function MoveNext() As Boolean Implements IEnumerator(Of Parent).MoveNext
            Return en_.MoveNext()
        End Function

        Public ReadOnly Property CurrentGeneric() As Parent Implements IEnumerator(Of Parent).Current
            Get
                Return en_.Current
            End Get
        End Property
        Public ReadOnly Property Current() As Object Implements IEnumerator.Current
            Get
                Return en_.Current
            End Get
        End Property
    End Class

    Public Overrides Function GetList() As IEnumerable(Of Parent)
        Return New Enumerable()
    End Function

    Public Sub New(ByVal n As Integer)
        MyBase.new(n)
        Children.Add(Me)
    End Sub

    Public Shared ReadOnly Children As New List(Of Child)

End Class

Module Program
    Sub Main()
        Dim p As Parent
        p = New Child(123)
        p = New Child(456)
        p = New Child(789)
        p.TestMethod()
    End Sub
End Module


引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -