2015-03-22T23:55:25の更新内容

programming/netfx/datetime/0_abstract/index.wiki.txt

current previous
1482,197 1482,6
 
2012/02/29 12:00:00 +00:00
2012/02/29 12:00:00 +00:00
 
}}
}}
 

        

        
+
****AddYearsとうるう年の考慮
+
うるう年の2月29日を表すDateTime・DateTimeOffsetに対してAddYearsメソッドで年単位の加減算を行う場合は注意が必要です。 うるう年の2月29日から年単位の加減算をした結果、その年もうるう年となる場合は2月29日、そうでない場合は2月28日が返されます(''3月1日にはなりません'')。
+

          
+
#tabpage(codelang=cs,container-title=AddYearsとn年前・n年後の2月29日)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    var baseDate = new DateTime(2012, 2, 29);
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1));
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1));
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4));
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4));
+
    Console.WriteLine();
+

          
+
    baseDate = new DateTime(2016, 2, 29);
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1));
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1));
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4));
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Module Sample
+
  Sub Main()
+
    Dim baseDate As New DateTime(2012, 2, 29)
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1))
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1))
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4))
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4))
+
    Console.WriteLine()
+

          
+
    baseDate = New DateTime(2016, 2, 29)
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1))
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1))
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4))
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4))
+
  End Sub
+
End Module
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
2012/02/29 0:00:00 + 1 years = 2013/02/28 0:00:00
+
2012/02/29 0:00:00 - 1 years = 2011/02/28 0:00:00
+
2012/02/29 0:00:00 + 4 years = 2016/02/29 0:00:00
+
2012/02/29 0:00:00 - 4 years = 2008/02/29 0:00:00
+

          
+
2016/02/29 0:00:00 + 1 years = 2017/02/28 0:00:00
+
2016/02/29 0:00:00 - 1 years = 2015/02/28 0:00:00
+
2016/02/29 0:00:00 + 4 years = 2020/02/29 0:00:00
+
2016/02/29 0:00:00 - 4 years = 2012/02/29 0:00:00
+
}}
+

          
+
一方、2月28日または3月1日を表すDateTime・DateTimeOffsetに対してAddYearsメソッドを用いる場合は、その年がうるう年となるか否かに関わらず、結果は2月28日または3月1日となります。
+

          
+
#tabpage(codelang=cs,container-title=AddYearsとn年前・n年後の2月28日・3月1日)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    var baseDate = new DateTime(2012, 2, 28);
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1));
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1));
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4));
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4));
+
    Console.WriteLine();
+

          
+
    baseDate = new DateTime(2016, 3, 1);
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1));
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1));
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4));
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Module Sample
+
  Sub Main()
+
    Dim baseDate As New DateTime(2012, 2, 28)
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1))
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1))
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4))
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4))
+
    Console.WriteLine()
+

          
+
    baseDate = New DateTime(2016, 3, 1)
+

          
+
    Console.WriteLine("{0} + 1 years = {1}", baseDate, baseDate.AddYears(+1))
+
    Console.WriteLine("{0} - 1 years = {1}", baseDate, baseDate.AddYears(-1))
+
    Console.WriteLine("{0} + 4 years = {1}", baseDate, baseDate.AddYears(+4))
+
    Console.WriteLine("{0} - 4 years = {1}", baseDate, baseDate.AddYears(-4))
+
  End Sub
+
End Module
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
2012/02/28 0:00:00 + 1 years = 2013/02/28 0:00:00
+
2012/02/28 0:00:00 - 1 years = 2011/02/28 0:00:00
+
2012/02/28 0:00:00 + 4 years = 2016/02/28 0:00:00
+
2012/02/28 0:00:00 - 4 years = 2008/02/28 0:00:00
+

          
+
2016/03/01 0:00:00 + 1 years = 2017/03/01 0:00:00
+
2016/03/01 0:00:00 - 1 years = 2015/03/01 0:00:00
+
2016/03/01 0:00:00 + 4 years = 2020/03/01 0:00:00
+
2016/03/01 0:00:00 - 4 years = 2012/03/01 0:00:00
+
}}
+

          
+
-関連: [[#DateTime_IsLeapYear]]
+

          
+
****AddMonthsと月ごとの日数の考慮
+
AddMonthsメソッドで月単位の加減算を行った結果その月の末日を超える場合は、日付の部分はその月の末日となります。 例えば、1月31日から3ヶ月加算した場合、4月31日は4月の末日を超えるため結果は4月30日となります。 同様に、1月31日から1ヶ月加算した場合、結果はうるう年であれば2月28日、そうでなければ2月29日となります。
+

          
+
#tabpage(codelang=cs,container-title=AddMonthsと1月31日のnヶ月後)
+
#code{{
+
using System;
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    var baseDate = new DateTime(2015, 1, 31);
+

          
+
    Console.WriteLine("{0} + 1 months = {1}", baseDate, baseDate.AddMonths(+1));
+
    Console.WriteLine("{0} + 2 months = {1}", baseDate, baseDate.AddMonths(+2));
+
    Console.WriteLine("{0} + 3 months = {1}", baseDate, baseDate.AddMonths(+3));
+
    Console.WriteLine();
+

          
+
    baseDate = new DateTime(2016, 1, 31);
+

          
+
    Console.WriteLine("{0} + 1 months = {1}", baseDate, baseDate.AddMonths(+1));
+
    Console.WriteLine("{0} + 2 months = {1}", baseDate, baseDate.AddMonths(+2));
+
    Console.WriteLine("{0} + 3 months = {1}", baseDate, baseDate.AddMonths(+3));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Module Sample
+
  Sub Main()
+
    Dim baseDate As New DateTime(2015, 1, 31)
+

          
+
    Console.WriteLine("{0} + 1 months = {1}", baseDate, baseDate.AddMonths(+1))
+
    Console.WriteLine("{0} + 2 months = {1}", baseDate, baseDate.AddMonths(+2))
+
    Console.WriteLine("{0} + 3 months = {1}", baseDate, baseDate.AddMonths(+3))
+
    Console.WriteLine()
+

          
+
    baseDate = New DateTime(2016, 1, 31)
+

          
+
    Console.WriteLine("{0} + 1 months = {1}", baseDate, baseDate.AddMonths(+1))
+
    Console.WriteLine("{0} + 2 months = {1}", baseDate, baseDate.AddMonths(+2))
+
    Console.WriteLine("{0} + 3 months = {1}", baseDate, baseDate.AddMonths(+3))
+
  End Sub
+
End Module
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
2015/01/31 0:00:00 + 1 months = 2015/02/28 0:00:00
+
2015/01/31 0:00:00 + 2 months = 2015/03/31 0:00:00
+
2015/01/31 0:00:00 + 3 months = 2015/04/30 0:00:00
+

          
+
2016/01/31 0:00:00 + 1 months = 2016/02/29 0:00:00
+
2016/01/31 0:00:00 + 2 months = 2016/03/31 0:00:00
+
2016/01/31 0:00:00 + 3 months = 2016/04/30 0:00:00
+
}}
+

          
+
-関連
+
--[[#DateTime_DaysInMonth]]
+
--[[programming/netfx/tips/get_last_day_of_month]]
+

          
 
***日時同士の差 [#DateTime_Subtract]
***日時同士の差 [#DateTime_Subtract]
 
&msdn(netfx,member,System.DateTime.Subtract){DateTime.Subtract};および&msdn(netfx,member,System.DateTimeOffset.Subtract){DateTimeOffset.Subtract};メソッドは、日時に対する減算を行う目的のほかにも、二つの日時同士の減算を行いその時間差を求める目的でも使うことができます。 日時同士の差を求めるため、このメソッドの戻り値は時間間隔を表す[[TimeSpan>#TimeSpan]]となります。
&msdn(netfx,member,System.DateTime.Subtract){DateTime.Subtract};および&msdn(netfx,member,System.DateTimeOffset.Subtract){DateTimeOffset.Subtract};メソッドは、日時に対する減算を行う目的のほかにも、二つの日時同士の減算を行いその時間差を求める目的でも使うことができます。 日時同士の差を求めるため、このメソッドの戻り値は時間間隔を表す[[TimeSpan>#TimeSpan]]となります。
 

        

        

programming/netfx/reflection/index.wiki.txt

current previous
568,7 568,7
 

        

        
 
-関連: [[programming/netfx/classlibrary/2_xmldoccomments#xmlelement_memberid]]
-関連: [[programming/netfx/classlibrary/2_xmldoccomments#xmlelement_memberid]]
 

        

        
~
**アセンブリからの型情報の取得 [#Assembly.GetType]
**アセンブリからの型情報の取得
 
''アセンブリ''とは何かを簡略に説明すると、EXEファイルあるはDLLファイルから読み込まれた実行可能コードとメタデータのセットのことです。 (より正確には、実行可能コードとメタデータのセットである''モジュール''を格納したもの) 特定のEXEやDLLで定義されている型情報を取得したい場合には、まず次のようなメソッドによってアセンブリを取得する必要があります。
''アセンブリ''とは何かを簡略に説明すると、EXEファイルあるはDLLファイルから読み込まれた実行可能コードとメタデータのセットのことです。 (より正確には、実行可能コードとメタデータのセットである''モジュール''を格納したもの) 特定のEXEやDLLで定義されている型情報を取得したい場合には、まず次のようなメソッドによってアセンブリを取得する必要があります。
 

        

        
 
|*アセンブリを取得するためのメソッド
|*アセンブリを取得するためのメソッド
763,7 763,7
 
|~|&msdn(netfx,member,System.Type.IsPublic){IsPublic};|型がパブリックかどうか|
|~|&msdn(netfx,member,System.Type.IsPublic){IsPublic};|型がパブリックかどうか|
 
|~|&msdn(netfx,member,System.Type.IsNotPublic){IsNotPublic};|型が非パブリックかどうか|
|~|&msdn(netfx,member,System.Type.IsNotPublic){IsNotPublic};|型が非パブリックかどうか|
 
|~|&msdn(netfx,member,System.Type.IsNested){IsNested};|型が入れ子になっているか(他の型の内部で宣言されているか)|
|~|&msdn(netfx,member,System.Type.IsNested){IsNested};|型が入れ子になっているか(他の型の内部で宣言されているか)|
~
|~|&msdn(netfx,member,System.Type.BaseType){BaseType};|基底クラス(継承元)の型情報 (関連:[[programming/netfx/tips/check_type_isassignablefrom_issubclassof#Type.BaseType]])|
|~|&msdn(netfx,member,System.Type.BaseType){BaseType};|基底クラス(継承元)の型情報|
 
|~ジェネリック型|&msdn(netfx,member,System.Type.IsGenericType){IsGenericType};|ジェネリック型かどうか&br;(オープン型``List<>``とクローズ型``List<int>``のどちらでもtrueとなる)|
|~ジェネリック型|&msdn(netfx,member,System.Type.IsGenericType){IsGenericType};|ジェネリック型かどうか&br;(オープン型``List<>``とクローズ型``List<int>``のどちらでもtrueとなる)|
 
|~|&msdn(netfx,member,System.Type.IsGenericTypeDefinition){IsGenericTypeDefinition};|ジェネリック型定義(オープンジェネリック型)かどうか&br;(オープン型``List<>``ではtrue、クローズ型``List<int>``ではfalseとなる)|
|~|&msdn(netfx,member,System.Type.IsGenericTypeDefinition){IsGenericTypeDefinition};|ジェネリック型定義(オープンジェネリック型)かどうか&br;(オープン型``List<>``ではtrue、クローズ型``List<int>``ではfalseとなる)|
 
|~|&msdn(netfx,member,System.Type.IsConstructedGenericType){IsConstructedGenericType};|構築ジェネリック型(クローズジェネリック型)かどうか&br;(オープン型``List<>``ではfalse、クローズ型``List<int>``ではtrueとなる)|
|~|&msdn(netfx,member,System.Type.IsConstructedGenericType){IsConstructedGenericType};|構築ジェネリック型(クローズジェネリック型)かどうか&br;(オープン型``List<>``ではfalse、クローズ型``List<int>``ではtrueとなる)|
986,7 986,7
 
--[[programming/netfx/delegate/2_operations]]
--[[programming/netfx/delegate/2_operations]]
 

        

        
 

        

        
~
****実装しているインターフェイスを調べる [#Type.GetInterfaces]
****実装しているインターフェイスを調べる
 
型が実装するすべてのインターフェイスを取得するには&msdn(netfx,member,System.Type.GetInterfaces){GetInterfacesメソッド};を使うことができます。 一方、型が特定のインターフェイスを実装しているかどうかについては、&msdn(netfx,member,System.Type.GetInterface){GetInterfaceメソッド};でインターフェイス名を文字列で指定して調べるか、&msdn(netfx,member,System.Type.IsAssignableFrom){IsAssignableFromメソッド};を使ってインターフェイス型への代入を行えるかどうかを調べることによって知ることができます。
型が実装するすべてのインターフェイスを取得するには&msdn(netfx,member,System.Type.GetInterfaces){GetInterfacesメソッド};を使うことができます。 一方、型が特定のインターフェイスを実装しているかどうかについては、&msdn(netfx,member,System.Type.GetInterface){GetInterfaceメソッド};でインターフェイス名を文字列で指定して調べるか、&msdn(netfx,member,System.Type.IsAssignableFrom){IsAssignableFromメソッド};を使ってインターフェイス型への代入を行えるかどうかを調べることによって知ることができます。
 

        

        
 
#tabpage(codelang=cs,container-title=実装しているインターフェイスを調べる)
#tabpage(codelang=cs,container-title=実装しているインターフェイスを調べる)

programming/netfx/tips/calc_elapsed_years/index.wiki.txt

current previous
60,73 60,37
 
}}
}}
 

        

        
 

        

        
~
*経過月数・経過年数
*経過年数
~
一方、TimeSpanには経過月数・経過年数を求めるプロパティは用意されていない。 経過日数(TimeSpan.TotalDays)から求めるにしても期間をまたがる月毎の日数の違いや閏年などを考慮して計算する必要がある。
一方、TimeSpanには経過年数を求めるプロパティは用意されていない。 経過日数(TimeSpan.TotalDays)から求めるにしても月毎の日数の違いや閏年などを考慮する必要がある。
 

        

        
~
経過月数(満月数)を求めるには、まず二つのDateTimeから月数のみの単純な差を求め、次に日付を比較し同日に達していなければ-1することで求めることができる。 なお以下の例では、日付の日部分が期間終了月の日数を超える場合には末日に達した時点で満1ヶ月としている(詳細はサンプル中のコメントおよび実行結果を参照)。
経過年数(満年数)を求めるには、まず二つのDateTimeから年数のみの単純な差を求め、次に日付を比較し同月同日に達していなければ-1することで求めることができる。
 

        

        
~
また経過年数(満年数)を求めるには、先に経過月数(満月数)を求め、満12ヶ月を満1年として求める。
#tabpage(codelang=cs,container-title=経過年数・満年数の取得)
+

          
+
#tabpage(codelang=cs,container-title=満月数・満年数の取得)
 
#code{{
#code{{
 
using System;
using System;
 

        

        
 
class Sample {
class Sample {
~
  // 基準日baseDayからdayまでの経過月数を求める
  // 基準日baseDayからdayまでの経過年数を求める
~
  // (DateTimeの時間部分に付いては考慮しない)
  public static int GetElapsedYears(DateTime baseDay, DateTime day)
+
  public static int GetElapsedMonths(DateTime baseDay, DateTime day)
 
  {
  {
 
    if (day < baseDay)
    if (day < baseDay)
 
      // 日付が基準日より前の場合は例外とする
      // 日付が基準日より前の場合は例外とする
 
      throw new ArgumentException();
      throw new ArgumentException();
 

        

        
~
    // 経過月数を求める(満月数を考慮しない単純計算)
    // 経過年数を求める(満年数を考慮しない単純計算)
~
    var elapsedMonths = (day.Year - baseDay.Year) * 12 + (day.Month - baseDay.Month);
    var elapsedYears = day.Year - baseDay.Year;
 

        

        
~
    if (baseDay.Day <= day.Day)
    // 指定された年における同月同日に達しているか調べる
~
      // baseDayの日部分がdayの日部分以上の場合は、その月を満了しているとみなす
    if (day < new DateTime(day.Year, baseDay.Month, baseDay.Day))
~
      // (例:1月30日→3月30日以降の場合は満(3-1)ヶ月)
      // 同月同日に達していなければ、経過年数を-1する
~
      return elapsedMonths;
      elapsedYears -= 1;
+
    else if (day.Day == DateTime.DaysInMonth(day.Year, day.Month) && day.Day <= baseDay.Day)
+
      // baseDayの日部分がdayの表す月の末日以降の場合は、その月を満了しているとみなす
+
      // (例:1月30日→2月28日(平年2月末日)/2月29日(閏年2月末日)以降の場合は満(2-1)ヶ月)
+
      return elapsedMonths;
+
    else
+
      // それ以外の場合は、その月を満了していないとみなす
+
      // (例:1月30日→3月29日以前の場合は(3-1)ヶ月未満、よって満(3-1-1)ヶ月)
+
      return elapsedMonths - 1;
+
  }
 

        

        
~
  // 基準日baseDayからdayまでの経過年数を求める
    return elapsedYears;
+
  public static int GetElapsedYears(DateTime baseDay, DateTime day)
+
  {
+
    // 経過月数÷12(端数切り捨て)したものを経過年数とする
+
    // (満12ヶ月で満1年とする)
+
    return GetElapsedMonths(baseDay, day) / 12;
 
  }
  }
 

        

        
 
  public static void Main()
  public static void Main()
 
  {
  {
~
    var baseDay = new DateTime(2012, 1, 30);
    var baseDay = new DateTime(2011, 6, 18);
+

          
+
    Console.WriteLine("基準日: {0:D}", baseDay);
+

          
+
    foreach (var day in new[] {
+
      new DateTime(2012, 1, 31),
+
      new DateTime(2012, 2, 28),
+
      new DateTime(2012, 2, 29),
+
      new DateTime(2012, 3, 29),
+
      new DateTime(2012, 3, 30),
+
      new DateTime(2012, 3, 31),
+
      new DateTime(2012, 4, 29),
+
      new DateTime(2012, 4, 30),
+
      new DateTime(2013, 1, 29),
+
      new DateTime(2013, 1, 30),
+
    }) {
+
      Console.WriteLine("日付: {0:D}, 経過月数: {1}", day, GetElapsedMonths(baseDay, day));
+
    }
+

          
+
    baseDay = new DateTime(2011, 6, 18);
 

        

        
 
    Console.WriteLine("基準日: {0:D}", baseDay);
    Console.WriteLine("基準日: {0:D}", baseDay);
 

        

        
138,21 102,97
 
    }) {
    }) {
 
      Console.WriteLine("日付: {0:D}, 経過年数: {1}", day, GetElapsedYears(baseDay, day));
      Console.WriteLine("日付: {0:D}, 経過年数: {1}", day, GetElapsedYears(baseDay, day));
 
    }
    }
-
  }
-
}
-
}}
-
#tabpage(codelang=vb)
-
#code{{
-
Imports System
-

          
-
Module Sample
-
  ' 基準日baseDayからdayまでの経過年数を求める
-
  Public Function GetElapsedYears(ByVal baseDay As DateTime, ByVal day As  DateTime) As Integer
-
    ' 日付が基準日より前の場合は例外とする
-
    If day < baseDay Then Throw New ArgumentException()
-

          
-
    ' 経過年数を求める(満年数を考慮しない単純計算)
-
    Dim elapsedYears As Integer = day.Year - baseDay.Year
-

          
-
    ' 指定された年における同月同日に達しているか調べる
-
    If day < New DateTime(day.Year, baseDay.Month, baseDay.Day) Then
-
      ' 同月同日に達していなければ、経過年数を-1する
-
      elapsedYears -= 1
-
    End If
-

          
-
    Return elapsedYears
-
  End Function
-

          
-
  Sub Main()
-
    Dim baseDay As New DateTime(2011, 6, 18)
-

          
-
    Console.WriteLine("基準日: {0:D}", baseDay)
-

          
-
    For Each day As DateTime In New DateTime() { _
-
      New DateTime(2012, 6, 17), _
-
      New DateTime(2012, 6, 18), _
-
      New DateTime(2015, 6, 17), _
-
      New DateTime(2015, 6, 18) _
-
    }
-
      Console.WriteLine("日付: {0:D}, 経過年数: {1}", day, GetElapsedYears(baseDay, day))
-
    Next
-
  End Sub
-
End Module
-
}}
-
#tabpage-end
-

          
-
#prompt(出力例){{
-
基準日: 2011年6月18日
-
日付: 2012年6月17日, 経過年数: 0
-
日付: 2012年6月18日, 経過年数: 1
-
日付: 2015年6月17日, 経過年数: 3
-
日付: 2015年6月18日, 経過年数: 4
-
}}
-

          
-
*経過月数
-
経過年数の場合と同様に、まず二つのDateTimeから月数のみの単純な差を求め、次に日付を比較し同日に達していなければ-1することで求めることができる。
-

          
-
#tabpage(codelang=cs,container-title=経過月数・満月数の取得)
-
#code{{
-
using System;
-

          
-
class Sample {
-
  // 基準日baseDayからdayまでの経過月数を求める
-
  public static int GetElapsedMonths(DateTime baseDay, DateTime day)
-
  {
-
    if (day < baseDay)
-
      // 日付が基準日より前の場合は例外とする
-
      throw new ArgumentException();
-

          
-
    // 経過月数を求める(満月数を考慮しない単純計算)
-
    var elapsedMonths = (day.Year - baseDay.Year) * 12 + (day.Month - baseDay.Month);
-

          
-
    // 指定された年・月における同日に達しているか調べる
-
    if (day < new DateTime(day.Year, day.Month, baseDay.Day))
-
      // 同日に達していなければ、経過月数を-1する
-
      elapsedMonths -= 1;
 

        

        
~
    baseDay = new DateTime(2012, 2, 29);
    return elapsedMonths;
-
  }
-

          
-
  public static void Main()
-
  {
-
    var baseDay = new DateTime(2011, 6, 18);
 

        

        
 
    Console.WriteLine("基準日: {0:D}", baseDay);
    Console.WriteLine("基準日: {0:D}", baseDay);
 

        

        
 
    foreach (var day in new[] {
    foreach (var day in new[] {
~
      new DateTime(2012, 3, 28),
      new DateTime(2011, 7, 17),
~
      new DateTime(2012, 3, 29),
      new DateTime(2011, 7, 18),
~
      new DateTime(2013, 2, 27),
      new DateTime(2012, 6, 18),
~
      new DateTime(2013, 2, 28),
      new DateTime(2015, 6, 17),
~
      new DateTime(2013, 3, 1),
      new DateTime(2015, 6, 18),
+
      new DateTime(2016, 2, 28),
+
      new DateTime(2016, 2, 29),
 
    }) {
    }) {
~
      Console.WriteLine("日付: {0:D}, 経過月数: {1}, 経過年数: {2}", day, GetElapsedMonths(baseDay, day), GetElapsedYears(baseDay, day));
      Console.WriteLine("日付: {0:D}, 経過月数: {1}", day, GetElapsedMonths(baseDay, day));
 
    }
    }
 
  }
  }
 
}
}
163,83 203,35
 

        

        
 
Module Sample
Module Sample
 
  ' 基準日baseDayからdayまでの経過月数を求める
  ' 基準日baseDayからdayまでの経過月数を求める
~
  ' (DateTimeの時間部分に付いては考慮しない)
  Public Function GetElapsedMonths(ByVal baseDay As DateTime, ByVal day As  DateTime) As Integer
+
  Public Function GetElapsedMonths(ByVal baseDay As DateTime, ByVal day As DateTime) As Integer
 
    ' 日付が基準日より前の場合は例外とする
    ' 日付が基準日より前の場合は例外とする
 
    If day < baseDay Then Throw New ArgumentException()
    If day < baseDay Then Throw New ArgumentException()
 

        

        
 
    ' 経過月数を求める(満月数を考慮しない単純計算)
    ' 経過月数を求める(満月数を考慮しない単純計算)
 
    Dim elapsedMonths As Integer = (day.Year - baseDay.Year) * 12 + (day.Month - baseDay.Month)
    Dim elapsedMonths As Integer = (day.Year - baseDay.Year) * 12 + (day.Month - baseDay.Month)
 

        

        
~
    If baseDay.Day <= day.Day Then
    ' 指定された年・月における同日に達しているか調べる
~
      ' baseDayの日部分がdayの日部分以上の場合は、その月を満了しているとみなす
    If day < New DateTime(day.Year, day.Month, baseDay.Day) Then
~
      ' (例:1月30日→3月30日以降の場合は満(3-1)ヶ月)
      ' 同日に達していなければ、経過月数を-1する
~
      Return elapsedMonths
      elapsedMonths -= 1
+
    Else If day.Day = DateTime.DaysInMonth(day.Year, day.Month) AndAlso day.Day <= baseDay.Day
+
      ' baseDayの日部分がdayの表す月の末日以降の場合は、その月を満了しているとみなす
+
      ' (例:1月30日→2月28日(平年2月末日)/2月29日(閏年2月末日)以降の場合は満(2-1)ヶ月)
+
      Return elapsedMonths
+
    Else
+
      ' それ以外の場合は、その月を満了していないとみなす
+
      ' (例:1月30日→3月29日以前の場合は(3-1)ヶ月未満、よって満(3-1-1)ヶ月)
+
      Return elapsedMonths - 1
 
    End If
    End If
+
  End Function
 

        

        
~
  ' 基準日baseDayからdayまでの経過年数を求める
    Return elapsedMonths
+
  Public Function GetElapsedYears(ByVal baseDay As DateTime, ByVal day As DateTime) As Integer
+
    ' 経過月数÷12(端数切り捨て)したものを経過年数とする
+
    ' (満12ヶ月で満1年とする)
+
    Return GetElapsedMonths(baseDay, day) \ 12
 
  End Function
  End Function
 

        

        
 
  Sub Main()
  Sub Main()
~
    Dim baseDay As New DateTime(2012, 1, 30)
    Dim baseDay As New DateTime(2011, 6, 18)
+

          
+
    Console.WriteLine("基準日: {0:D}", baseDay)
+

          
+
    For Each day As DateTime In New DateTime() { _
+
      New DateTime(2012, 1, 31), _
+
      New DateTime(2012, 2, 28), _
+
      New DateTime(2012, 2, 29), _
+
      New DateTime(2012, 3, 29), _
+
      New DateTime(2012, 3, 30), _
+
      New DateTime(2012, 3, 31), _
+
      New DateTime(2012, 4, 29), _
+
      New DateTime(2012, 4, 30), _
+
      New DateTime(2013, 1, 29), _
+
      New DateTime(2013, 1, 30)
+
    }
+
      Console.WriteLine("日付: {0:D}, 経過月数: {1}", day, GetElapsedMonths(baseDay, day))
+
    Next
+

          
+
    baseDay = New DateTime(2011, 6, 18)
 

        

        
 
    Console.WriteLine("基準日: {0:D}", baseDay)
    Console.WriteLine("基準日: {0:D}", baseDay)
 

        

        
 
    For Each day As DateTime In New DateTime() { _
    For Each day As DateTime In New DateTime() { _
~
      New DateTime(2012, 6, 17), _
      New DateTime(2011, 7, 17), _
-
      New DateTime(2011, 7, 18), _
 
      New DateTime(2012, 6, 18), _
      New DateTime(2012, 6, 18), _
 
      New DateTime(2015, 6, 17), _
      New DateTime(2015, 6, 17), _
 
      New DateTime(2015, 6, 18) _
      New DateTime(2015, 6, 18) _
 
    }
    }
~
      Console.WriteLine("日付: {0:D}, 経過年数: {1}", day, GetElapsedYears(baseDay, day))
      Console.WriteLine("日付: {0:D}, 経過月数: {1}", day, GetElapsedMonths(baseDay, day))
+
    Next
+

          
+
    baseDay = New DateTime(2012, 2, 29)
+

          
+
    Console.WriteLine("基準日: {0:D}", baseDay)
+

          
+
    For Each day As DateTime In New DateTime() { _
+
      New DateTime(2012, 3, 28), _
+
      New DateTime(2012, 3, 29), _
+
      New DateTime(2013, 2, 27), _
+
      New DateTime(2013, 2, 28), _
+
      New DateTime(2013, 3, 1), _
+
      New DateTime(2016, 2, 28), _
+
      New DateTime(2016, 2, 29) _
+
    }
+
      Console.WriteLine("日付: {0:D}, 経過月数: {1}, 経過年数: {2}", day, GetElapsedMonths(baseDay, day), GetElapsedYears(baseDay, day))
 
    Next
    Next
 
  End Sub
  End Sub
 
End Module
End Module
247,31 239,15
 
#tabpage-end
#tabpage-end
 

        

        
 
#prompt(出力例){{
#prompt(出力例){{
+
基準日: 2012年1月30日
+
日付: 2012年1月31日, 経過月数: 0
+
日付: 2012年2月28日, 経過月数: 0
+
日付: 2012年2月29日, 経過月数: 1
+
日付: 2012年3月29日, 経過月数: 1
+
日付: 2012年3月30日, 経過月数: 2
+
日付: 2012年3月31日, 経過月数: 2
+
日付: 2012年4月29日, 経過月数: 2
+
日付: 2012年4月30日, 経過月数: 3
+
日付: 2013年1月29日, 経過月数: 11
+
日付: 2013年1月30日, 経過月数: 12
 
基準日: 2011年6月18日
基準日: 2011年6月18日
~
日付: 2012年6月17日, 経過年数: 0
日付: 2011年7月17日, 経過月数: 0
~
日付: 2012年6月18日, 経過年数: 1
日付: 2011年7月18日, 経過月数: 1
~
日付: 2015年6月17日, 経過年数: 3
日付: 2012年6月18日, 経過月数: 12
~
日付: 2015年6月18日, 経過年数: 4
日付: 2015年6月17日, 経過月数: 47
~
基準日: 2012年2月29日
日付: 2015年6月18日, 経過月数: 48
+
日付: 2012年3月28日, 経過月数: 0, 経過年数: 0
+
日付: 2012年3月29日, 経過月数: 1, 経過年数: 0
+
日付: 2013年2月27日, 経過月数: 11, 経過年数: 0
+
日付: 2013年2月28日, 経過月数: 12, 経過年数: 1
+
日付: 2013年3月1日, 経過月数: 12, 経過年数: 1
+
日付: 2016年2月28日, 経過月数: 47, 経過年数: 3
+
日付: 2016年2月29日, 経過月数: 48, 経過年数: 4
 
}}
}}
 

        

        
 

        

        
 

        

        
-

          
-

          

programming/netfx/tips/check_type_isassignablefrom_issubclassof/index.wiki.txt

current previous
10,14 10,13
 
-関連するページ
-関連するページ
 
#ls2_1(programming/netfx/conversion)
#ls2_1(programming/netfx/conversion)
 
--[[programming/netfx/reflection]]
--[[programming/netfx/reflection]]
+
---[[programming/netfx/reflection#IsDelegate]]
 
--[[programming/vb.net/operator_is_isnot_typeof]] (VB)
--[[programming/vb.net/operator_is_isnot_typeof]] (VB)
 
--[[programming/netfx/tips/plugin_assembly]]
--[[programming/netfx/tips/plugin_assembly]]
 

        

        
 
*インスタンスと継承関係・代入可能性の判定
*インスタンスと継承関係・代入可能性の判定
~
``is``演算子(C#)・``TypeOf``演算子(VB)を使うことで、インスタンスが''特定の型と同じ型''か、もしくは''特定の型から派生した''ものかどうかを判定することができる。
is演算子(C#)やTypeOf演算子(VB)を使うことで、インスタンスがある型と同じか、もしくはある型から派生するものかどうかを判定できる。
 

        

        
~
#tabpage(codelang=cs,container-title=インスタンスが特定の型か、あるいはその派生クラスか調べる)
#tabpage(codelang=cs)
 
#code{{
#code{{
 
using System;
using System;
 

        

        
82,9 81,9
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
~
型の継承関係ではなく、インスタンスが''特定のインターフェイスを実装しているか''、またインスタンスが''特定の型の変数に代入可能かどうか''(型に互換性・代入可能性があるか)を判定したい場合にも``is``演算子(C#)・``TypeOf``演算子(VB)を使うことが出来る。
継承関係ではなく実装しているインターフェイスなど、インスタンスが別の型の変数に''代入可能かどうか''(型に互換性があるか)を判定したい場合も、is演算子(C#)やTypeOf演算子(VB)を使うことが出来る。
 

        

        
~
#tabpage(codelang=cs,container-title=インスタンスが特定のインターフェイスを実装しているか調べる)
#tabpage(codelang=cs)
 
#code{{
#code{{
 
using System;
using System;
 

        

        
103,6 102,8
 
    Console.WriteLine("instClass2 is IIfc2 = {0}", instClass2 is IIfc2);
    Console.WriteLine("instClass2 is IIfc2 = {0}", instClass2 is IIfc2);
 
    Console.WriteLine("instClass1 is IIfc2 = {0}", instClass1 is IIfc2);
    Console.WriteLine("instClass1 is IIfc2 = {0}", instClass1 is IIfc2);
 
    Console.WriteLine("instClass2 is IIfc1 = {0}", instClass2 is IIfc1);
    Console.WriteLine("instClass2 is IIfc1 = {0}", instClass2 is IIfc1);
-
    Console.WriteLine("instClass1 is int = {0}", instClass1 is int);
-
    Console.WriteLine("instClass1 is object = {0}", instClass1 is object);
 
  }
  }
 
}
}
 
}}
}}
112,6 113,8
 
instClass2 is IIfc2 = True
instClass2 is IIfc2 = True
 
instClass1 is IIfc2 = False
instClass1 is IIfc2 = False
 
instClass2 is IIfc1 = False
instClass2 is IIfc1 = False
-
instClass1 is int = False
-
instClass1 is object = True
 
}}
}}
 
#tabpage(codelang=vb)
#tabpage(codelang=vb)
 
#code{{
#code{{
131,6 134,8
 
    Console.WriteLine("TypeOf instClass2 Is IIfc2 = {0}", TypeOf instClass2 Is IIfc2)
    Console.WriteLine("TypeOf instClass2 Is IIfc2 = {0}", TypeOf instClass2 Is IIfc2)
 
    Console.WriteLine("TypeOf instClass1 Is IIfc2 = {0}", TypeOf instClass1 Is IIfc2)
    Console.WriteLine("TypeOf instClass1 Is IIfc2 = {0}", TypeOf instClass1 Is IIfc2)
 
    Console.WriteLine("TypeOf instClass2 Is IIfc1 = {0}", TypeOf instClass2 Is IIfc1)
    Console.WriteLine("TypeOf instClass2 Is IIfc1 = {0}", TypeOf instClass2 Is IIfc1)
-
    Console.WriteLine("TypeOf instClass1 Is Integer = {0}", TypeOf instClass1 Is Integer)
-
    Console.WriteLine("TypeOf instClass1 Is Object = {0}", TypeOf instClass1 Is Object)
 
  End Sub
  End Sub
 
End Class
End Class
 
}}
}}
140,58 145,15
 
TypeOf instClass2 Is IIfc2 = True
TypeOf instClass2 Is IIfc2 = True
 
TypeOf instClass1 Is IIfc2 = False
TypeOf instClass1 Is IIfc2 = False
 
TypeOf instClass2 Is IIfc1 = False
TypeOf instClass2 Is IIfc1 = False
+
}}
+
#tabpage-end
+

          
+
#tabpage(codelang=cs,container-title=インスタンスが特定の型の変数に代入可能かどうか調べる)
+
#code{{
+
using System;
+

          
+
class Class1 {}
+

          
+
class Sample {
+
  public static void Main()
+
  {
+
    object instClass1 = new Class1();
+

          
+
    Console.WriteLine("instClass1 is int = {0}", instClass1 is int);
+
    Console.WriteLine("instClass1 is object = {0}", instClass1 is object);
+
  }
+
}
+
}}
+

          
+
#prompt(実行結果){{
+
instClass1 is int = False
+
instClass1 is object = True
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Class Class1 : End Class
+

          
+
Class Sample
+
  Public Shared Sub Main()
+
    Dim instClass1 As Object = New Class1()
+

          
+
    Console.WriteLine("TypeOf instClass1 Is Integer = {0}", TypeOf instClass1 Is Integer)
+
    Console.WriteLine("TypeOf instClass1 Is Object = {0}", TypeOf instClass1 Is Object)
+
  End Sub
+
End Class
+
}}
+

          
+
#prompt(実行結果){{
 
TypeOf instClass1 Is Integer = False
TypeOf instClass1 Is Integer = False
 
TypeOf instClass1 Is Object = True
TypeOf instClass1 Is Object = True
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
+

          
+

          
 
*型情報と継承関係・代入可能性の判定
*型情報と継承関係・代入可能性の判定
~
&msdn(netfx,type,System.Type){Typeクラス};の&msdn(netfx,member,System.Type.IsSubclassOf){IsSubclassOfメソッド};を使うことで、型情報により型が特定の型から派生するものかどうかを判定できる。 ただし、IsSubclassOfメソッドは''同じ型を表す場合は``False``を返す''点に注意が必要で、完全に同じ型を表すかどうかを判定する場合は&msdn(netfx,member,System.Type.Equals){Type.Equalsメソッド};を用いて判定する必要がある。
&msdn(netfx,type,System.Type){Typeクラス};の&msdn(netfx,member,System.Type.IsSubclassOf){IsSubclassOfメソッド};を使うことで、型情報から型があるクラスから派生するものかどうかを判定できる。 ただし、このメソッドでは同じ型を表す場合はFalseを返される点に注意が必要で、同じクラスを表すかどうかを判定する場合は、&msdn(netfx,member,System.Type.Equals){Type.Equalsメソッド};もしくはis演算子(C#)やTypeOf演算子(VB)を使って判定する必要がある。
 

        

        
~
#tabpage(codelang=cs,container-title=型情報から型が特定の型の派生型かどうか調べる)
#tabpage(codelang=cs)
 
#code{{
#code{{
 
using System;
using System;
 

        

        
250,9 212,9
 
Base.IsSubclassOf(Base) = False
Base.IsSubclassOf(Base) = False
 
}}
}}
 

        

        
~
型が特定の型と同じか、あるいは特定の型から派生するかを判定するには&msdn(netfx,member,System.Type.IsAssignableFrom){Type.IsAssignableFromメソッド};を使うことができる。 このメソッドは型が''特定の型に代入可能かどうか''を判定することができる。 そのため、型が特定のインターフェイスを実装しているかどうかについてもこのメソッドで調べることができる。
継承関係ではなく実装しているインターフェイスなど、型が別の型に''代入可能かどうか''を判定したい場合は&msdn(netfx,member,System.Type.IsAssignableFrom){Type.IsAssignableFromメソッド};を使って調べることが出来る。
 

        

        
~
#tabpage(codelang=cs,container-title=型情報から型の代入可能性を調べる)
#tabpage(codelang=cs)
 
#code{{
#code{{
 
using System;
using System;
 

        

        
348,14 310,7
 
Class1.IsAssignableFrom(Class3) = True
Class1.IsAssignableFrom(Class3) = True
 
}}
}}
 

        

        
~

          
*基底クラスの取得
+
IsSubclassOfメソッドとIsAssignableFromメソッドでは引数の渡し方に注意する必要がある。
+

          
+
|*IsSubclassOfとIsAssignableFromの呼び出し
+
|型``TX``''が''基底型``TBase``の派生型かどうかを調べる場合|``TX.IsSubclassOf(TBase)``|
+
|型``TX``''から''型``TBase``に代入可能かどうかを調べる場合|``TBase.IsAssignableFrom(TX)``|
+

          
+
*基底クラスの取得 [#Type.BaseType]
 
基底クラスが具体的にどのような型か実行時まで知り得ない場合は、&msdn(netfx,member,System.Type.BaseType){Type.BaseTypeプロパティ};を参照することで継承している型の情報を得ることができる。
基底クラスが具体的にどのような型か実行時まで知り得ない場合は、&msdn(netfx,member,System.Type.BaseType){Type.BaseTypeプロパティ};を参照することで継承している型の情報を得ることができる。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
419,10 374,8
 
System.Object
System.Object
 
}}
}}
 

        

        
+
なお、``Object``型やインターフェイス型の場合、BaseTypeプロパティは``null``/``Nothing``を返す。
+

          
 
*インターフェイスの取得
*インターフェイスの取得
~
どのようなインターフェイスを実装しているか実行時まで知り得ない場合は、&msdn(netfx,member,System.Type.GetInterfaces){Type.GetInterfacesメソッド};を使用することで型が実装しているインターフェイスすべてを得ることができる。 このメソッドでは、基底クラスで実装されているインターフェイスも返される。
どのようなインターフェイスを実装しているか実行時まで知り得ない場合は、&msdn(netfx,member,System.Type.BaseType){Type.GetInterfacesメソッド};を使用することで型が実装しているインターフェイスすべてを得ることができる。 このメソッドでは、基底クラスで実装されているインターフェイスも返される。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
 
#code{{
#code{{
505,8 458,6
 

        

        
 
}}
}}
 

        

        
+
-関連:[[programming/netfx/reflection#Type.GetInterfaces]]
+

          
 

        

        
 
*派生クラスの取得
*派生クラスの取得
 
基底クラスの型情報から、そのクラスから派生しているクラスの情報を直接得ることはできない。 そのため派生クラスを取得するには、&msdn(netfx,member,System.Reflection.Assembly.GetTypes){Assembly.GetTypesメソッド};を使ってアセンブリで定義されているすべての型情報を走査し、Type.BaseTypeプロパティを参照して基底クラスが一致するものを1つずつ検索する。
基底クラスの型情報から、そのクラスから派生しているクラスの情報を直接得ることはできない。 そのため派生クラスを取得するには、&msdn(netfx,member,System.Reflection.Assembly.GetTypes){Assembly.GetTypesメソッド};を使ってアセンブリで定義されているすべての型情報を走査し、Type.BaseTypeプロパティを参照して基底クラスが一致するものを1つずつ検索する。
582,6 533,3
 
Class2
Class2
 

        

        
 
}}
}}
+

          
+
-関連:[[programming/netfx/reflection#Assembly.GetType]]
+