プログラム言語 データ型:型情報

規定値

var i1 = default(int);
i1:0
var i2 = int.MinValue;
i2:-2147483648
var i3 = int.MaxValue;
i3:2147483647

string s = default(string);
s:null
DataTime d = DataTime.MaxValue;
d:9999/12/31 23:59:59
DataTime d = DataTime.MinValue;
d:0001/01/01 0:00:00

型サイズ

int size;
size = sizeof(int); // size : 4
size = sizeof(char); // size : 4
size = sizeof(float); // size : 4

size = sizeof(string); // コンパイルエラー
size = sizeof(MyClass); // コンパイルエラー

型判定

bool b;
object[] o = new object[] { null, 5, '5', "5" };

b = o[0] is int; // b : false
b = o[1] is int; // b : true
b = o[2] is char; // b : true
b = o[3] is string; // b : true

MyClass c = new MyClass();
b = c is MyClass; // b : true

Null許容属性

int? i;
Null値許容のint型
Dim i As Nullable(Of Integer)
Null値許容のint型

キャスト

明示的な型変換

メモリ使用容量の大きい型から小さい型への変換はキャストが必要。
(クラスのキャストについては「オブジェクト指向: ポリモーフィズム/暗黙の変換/キャスト」参照)

long l = 100;
int i = (int) l;
int i = int.Parse("100");
int i = Convert.ToInt32("100");

string s = i.ToString();
string s = Convert.ToString("100");

文字列⇒数値
int myInt = int.Parse(s: "123");
int myInt = Convert.ToInt32(value: "123");

Null文字:""は変換できない。

as
object[] array = new object[]{null, 5, '5', "5"};

string s = array[1] as string;

↓と同じ①
string s;
try
{
  s = (string)array[1];
}
catch
{
  s = null;
}

↓と同じ②
if (array[1] is string)
{
  s = (string)array[1];
}
else
{
  s = null;
}

signed int before = -1;
int after = 10;

自動型変換(暗黙的型変換)
after = before;
変換/桁の切り捨てが自動で行われる

強制型変換(明示的型変換)
after = (int)before;

static_cast
after = static_cast<int>(before);

reinterpret_cast
int *p = &before;
after = static_cast<int>(p); ※エラー

after = reinterpret_cast<int>(p);

const_cast
LPCWSTR before = L"10";
LPWSTR after = L"10";
after = before; ※エラー

after = const_cast<LPWSTR>(before);

型判定
if (typeid(after) == typeid(LPCWSTR))
{
 ~
}

Dim s As String = Ctype(100 , String)
Dim s As String = DirectCast(100 , String)
Dim s As String = 100.ToString()
Dim s As String = Convert.ToString(100)
Dim s As String = String.Parse(100)
Dim s As String = CStr("100")
数値→文字
String s = String.valueOf(5)

文字→数値
int j;
j = Integer.parseInt("123");

文字列 → 日付型
$ret = strtotime('2018-01-01');

日付型 → 文字列
$ret = date( 'Y/m/d', strtotime('2018-01-01') );
$ret = date( 'Y/m/d H:i:s', strtotime('2018-01-01') );

文字列 → 数値型
$ret = intval('2018');

数値型 → 文字列
$ret = strval(2018);


$ret = (int)値; 整数へのキャスト(integerも可)
$ret = (bool)値; 論理値へのキャスト(booleanも可)
$ret = (float)値; floatへのキャスト(doubleも可)
$ret = (string)値; 文字列へのキャスト
$ret = (unset)値; NULLへのキャスト

print(1 + '1') # エラー
print(str(1) + '1') # 11
print(1 + int('1')) # 2
print(1 + float('1')) # 2.0
var s = String(100);
// ⇒ s : "100"
var s = "" + 100; も可

var f = parseFloat("3.14");
// ⇒ f : 3.14

var i = parseInt("3.14");
// ⇒ i : 3

暗黙の型変換

cast
メモリ使用容量の小さい型から大きい型への変換は変換可能。
short s = 10;
int i = s;
(クラスの型変換については「オブジェクト指向: ポリモーフィズム/暗黙の変換/キャスト」参照)

double d = 10.5;
int i = d;
⇒ i : 10
一部の情報が失われる場合あり

オペランドの型
short s = 10;
s = ++s;
⇒OK

s = s + 1;
⇒エラー。int型に変換される。
s = (short)(s + 1);
⇒OK

リフレクション

プログラムの実行時にメタデータを取り出す機能
クラス情報を動的に取得して実行も可能。
型情報の取得に関しては「オブジェクト指向: ポリモーフィズム/型情報」参照

動的処理

using System.Reflection;

class MyClass
{
 private int myInt;
 public MyClass(int prm)
 {
  this.myInt = prm;
 }
 public void MyFunc()
 {
  Console.WriteLine(this.myInt);
 }
}

static void Main(string[] args)
{

 静的なコーディングによる実行方法
 var m = new MyClass(prm: 5);
 m.MyFunc();
 
 動的なコーディングによる実行方法
 
 インスタンス作成
 Type t = typeof(MyClass);
 object target = t.InvokeMember(
  name: null,
  invokeAttr: BindingFlags.CreateInstance,
  binder: null,
  target: null,
  args: new object[] { 100 });
 
 プロパティ設定
 t.InvokeMember(
  name: "myInt",
  invokeAttr: BindingFlags.SetProperty,
  binder: null,
  target: target,
  args: new object[] { 50 });
 
 メソッド実行
 t.InvokeMember(
  name :"MyFunc",
  invokeAttr: BindingFlags.InvokeMethod,
  binder: null,
  target: target,
  args: null);
}

透過プロキシ

代理クラス(透過プロキシー)を使って、あたかも実際のクラス(SampleClass)を扱っているかの様にメソッド等を実行する方法

using System;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

class Program
{
 static void Main(string[] args)
 {
  透過プロキシ生成
  var proxy = new MyProxyClass(typeof(SampleClass));
  
  利用するクラスのインスタンスを生成
  var transparent = proxy.GetTransparentProxy() as SampleClass;
  
  透過プロキシを使用してメソッド呼び出し
  var ret = transparent.Add(10, 20);
  ret:30
 }
}

代理クラス(透過プロキシ)
public class MyProxyClass : RealProxy
{
 private Object myObjectInstance = null;
 private Type myType = null;
 
 public MyProxyClass(Type argType) : base(argType)
 {
  myType = argType;
  myObjectInstance = Activator.CreateInstance(argType);
 }
 
 引数の情報を頼りに、リフレクションの機能を使って、実際のメソッドを呼び出し、
 ReturnMessage に戻り値の情報を返す

 public override IMessage Invoke(IMessage msg)
 {
  var methodMsg = msg as IMethodMessage;
  
  Object retValue = myType.InvokeMember(
   name:methodMsg.MethodName,
   invokeAttr: BindingFlags.InvokeMethod,
   binder: null,
   target: myObjectInstance,
   args: methodMsg.Args);
   
  var retMsg = new ReturnMessage(
   ret: retValue,
   outArgs: null,
   outArgsCount: 0,
   callCtx: (msg as IMethodCallMessage).LogicalCallContext,
   mcm: msg as IMethodCallMessage);
   
  return retMsg;
 }
}

透過プロキシを通す、実際に使用するクラス
public class SampleClass : MarshalByRefObject
{
 public int Add(int a, int b)
 {
  return a + b;
 }
}