ソース掲示板




すべてから検索

キーワード   条件 表示 現行ログ 過去ログ トピックス 名前 本文

  メンテナンス 前画面に戻る

対象スレッド 件名: オブジェクトに対するオペレータの定義
名前: lightbox
処理選択
パスワード

件名 オブジェクトに対するオペレータの定義
名前 lightbox
コメント
@C:GREEN(
C++ での実装とは少し違うようですが、以下のような演算子を自分の作成したオブジェクト
に対して特別な実装を施す事ができます
)

@HTML
<STYLE type=text/css>#lboxtable * {	font-family: 'MS Pゴシック';	font-size: 12px;}#lboxtable table {	border-collapse: collapse;	border-style: solid;	border-color: #000000;	border-width: 1px;	background-color: #FFFFFF;}#lboxtable td {	padding: 5px;	border-style: solid;	border-color: #000000;	border-width: 1px;	white-space: nowrap;}#lboxtable th {	padding: 5px;	border-style: solid;	border-color: #000000;	border-width: 1px;	background-color: silver;	white-space: nowrap;}</STYLE><DIV id="lboxtable"><TABLE border="1"><TR><TH>Operator</TH><TH>Operand Count</TH><TH>Description</TH></TR><TR><TD>+</TD><TD>Unary</TD><TD>Positive</TD></TR><TR><TD>-</TD><TD>Unary</TD><TD>Negative</TD></TR><TR><TD>IsFalse</TD><TD>Unary</TD><TD>Is False test</TD></TR><TR><TD>IsTrue</TD><TD>Unary</TD><TD>Is True test</TD></TR><TR><TD>Not</TD><TD>Unary</TD><TD>Negation</TD></TR><TR><TD>+</TD><TD>Binary</TD><TD>Addition</TD></TR><TR><TD>-</TD><TD>Binary</TD><TD>Subtraction</TD></TR><TR><TD>*</TD><TD>Binary</TD><TD>Multiplication</TD></TR><TR><TD>/</TD><TD>Binary</TD><TD>Floating-point division</TD></TR><TR><TD>\</TD><TD>Binary</TD><TD>Integer division</TD></TR><TR><TD>&amp;</TD><TD>Binary</TD><TD>Concatenation</TD></TR><TR><TD>^</TD><TD>Binary</TD><TD>Exponentiation</TD></TR><TR><TD>&gt;&gt;</TD><TD>Binary</TD><TD>Shift right</TD></TR><TR><TD>&lt;&lt;</TD><TD>Binary</TD><TD>Shift left</TD></TR><TR><TD>=</TD><TD>Binary</TD><TD>Equality; assignment <BR>cannot be overloaded</TD></TR><TR><TD>&lt;&gt;</TD><TD>Binary</TD><TD>Not equal</TD></TR><TR><TD>&gt;</TD><TD>Binary</TD><TD>Greater than</TD></TR><TR><TD>&lt;</TD><TD>Binary</TD><TD>Less than</TD></TR><TR><TD>&gt;=</TD><TD>Binary</TD><TD>Greater than or equal to</TD></TR><TR><TD>&lt;=</TD><TD>Binary</TD><TD>Less than or equal to</TD></TR><TR><TD>And</TD><TD>Binary</TD><TD>Bitwise and</TD></TR><TR><TD>Like</TD><TD>Binary</TD><TD>String pattern matching</TD></TR><TR><TD>Mod</TD><TD>Binary</TD><TD>Modulo division</TD></TR><TR><TD>Or</TD><TD>Binary</TD><TD>Bitwise or</TD></TR><TR><TD>Xor</TD><TD>Binary</TD><TD>Bitwise xor</TD></TR><TR><TD>CType</TD><TD>Unary</TD><TD>Type conversion</TD></TR></TABLE></DIV>
@HEND

@DIV
実装時に知っておく必要のある仕様としては、

1) クラスメソッドとして定義する必要がえる
2) ペアとなる演算子は同時に定義する必要がある
3) 演算子によっては、引数の型が決められているものがある
4) 第1引数に、自分自身の型を定義する事によって呼ばれた時にインスタンスが引き渡される
@END

[[テスト用のレジストリを扱うクラス]]
@DIV
' **************************************************
' クラス定義
' **************************************************
Imports Microsoft.Win32

Public Class RegCur

	Public regkey As RegistryKey = Nothing
	Public svpath As String = Nothing


[[	' **************************************************
	' コンストラタ
	' **************************************************]]
	Public Sub New(ByVal path As String)

		regkey = Registry.CurrentUser.OpenSubKey(path, True)
		svpath = path

	End Sub

[[	' **************************************************
	' 比較演算子を代入して再OPENに利用
	' **************************************************]]
	Public Shared Operator =(ByVal target As RegCur, ByVal path As String) As Boolean

		Dim ret As Boolean = False

		If Not target.regkey Is Nothing Then
			target.regkey.Close()
		End If

		target.regkey = Registry.CurrentUser.OpenSubKey(path, True)
		If Not target.regkey Is Nothing Then
			ret = True
		End If

		Return ret

	End Operator

[[	' **************************************************
	' 比較演算子を代入して再OPENに利用
	' **************************************************]]
	Public Shared Operator <>(ByVal target As RegCur, ByVal path As String) As Boolean

		Dim ret As Boolean = False

		If Not target.regkey Is Nothing Then
			target.regkey.Close()
		End If

		target.regkey = Registry.CurrentUser.OpenSubKey(path, True)
		If target.regkey Is Nothing Then
			ret = True
		End If

		Return ret

	End Operator

[[	' **************************************************
	' C++ で言うところの キャスト演算子( String 用 )
	' Widening は 損失の無い変換
	' **************************************************]]
	Public Shared Widening Operator CType(ByVal value As RegCur) As String

		If value Is Nothing Then
			Return ""
		Else
			Return value.svpath
		End If

	End Operator

[[	' **************************************************
	' 演算子では無いが、String 用の Ctype と同じにする
	' デフォルトでは、クラス名が返る(含む名前空間)
	' **************************************************]]
	Public Overrides Function ToString() As String

		Return Me.svpath

	End Function

End Class
@END

@DIV
レジストリのキーを再度別のキーで開けなおす際に、 = の右辺がキーで、成功した時に true が返ります。
<> を使うと、成功した時に false が返ります。

( ※ = と <> は、本来比較演算子です )
@END

[[実行サンプル]]
@DIV
Imports Microsoft.Win32

Public Class Form1

	Private Sub Form1_Load(ByVal sender As System.Object, _
	 ByVal e As System.EventArgs) Handles MyBase.Load

		Dim reg As RegCur = New RegCur("Environment")

		MessageBox.Show(reg.regkey.GetValue("PATH").ToString())

		If reg = "Software\Microsoft\Ftp" Then
			MessageBox.Show(CStr(reg.regkey.GetValue("Use PASV")))
		Else
			MessageBox.Show("キーが存在しません")
		End If

		If reg = "Software\Microsoft\Internet Explorer" Then
			MessageBox.Show(CType(reg.regkey.GetValue("Download Directory"), String))
		Else
			MessageBox.Show("キーが存在しません")
		End If

		If reg <> "Environment" Then
			MessageBox.Show("キーが存在しません")
		Else
			MessageBox.Show(Convert.ToString(reg.regkey.GetValue("TMP")))
		End If

	End Sub
End Class
@END


@DIV
VB.NET では、通常自作オブジェクトを = や <> 演算子で比較しないので問題無いですが、
このまま C# に変換した場合は、C# では null との比較が存在するので考慮が必要です

[[VB での オブジォクトがインスタンスかどうかの判断]]
if Object is Nothing then
	' もともと is Nothing を使うので、= オペレターは使われない
end if

[[C# での オブジォクトがインスタンスかどうかの判断]]
if ( null == Object ) {
	// null を左辺に持って来る事によって、定義された == オペレータは発動しない
end if
@END


[[C#]]
@DIV
public class RegCur
{

	public RegistryKey regkey = null;
	public string svpath = null;

	public RegCur(string path)
	{

		regkey = Registry.CurrentUser.OpenSubKey(path, true);
		svpath = path;

	}

	public static bool operator ==(RegCur target, string path)
	{
		bool ret = false;

		if ((target.regkey != null))
		{
			target.regkey.Close();
		}

		target.regkey = Registry.CurrentUser.OpenSubKey(path, true);
		if ((target.regkey != null))
		{
			ret = true;
		}

		return ret;

	}

	public static bool operator !=(RegCur target, string path)
	{

		bool ret = false;

		if ((target.regkey != null))
		{
			target.regkey.Close();
		}

		target.regkey = Registry.CurrentUser.OpenSubKey(path, true);
		if (target.regkey == null)
		{
			ret = true;
		}

		return ret;

	}

}
@END