デリゲート内部で起こっていること
■ 型定義
インスタンスと関数ポインターのペア。
記述されているものと別で、2つのフィールドがあって、
1つは、マルチキャスト用、もう一つは静的メソッドのために使うフィールドが
作られる。
■ デリゲートのインスタンス生成
デリゲート型の変数に対してメソッドを直接渡すような形でデリゲートを作る。
■ 静的メソッドを渡すと遅い
デリゲートはインスタンスメソッドの時に処理が単純で高速になるように作られている。
C#ではインスタンスメソッドの方が圧倒的に利用頻度が高いので、インスタンスメソッドに
対して最適化したほうが、全体としてのパフォーマンスは上がる。
■ カリー化デリゲート
デリゲート越しの静的メソッドの呼び出しを早くする方法が1つある。
カリー化デリゲートという手段を使うと、インスタンスメソッドと同じで
静的メソッドを呼べるようになる。
拡張メソッドは、実体として、第1引数でインスタンスを受け取る構造になっていて
これがインスタンスメソッドの暗黙的なthis引数と同じ受け取り方になっている。
---------------------------------------------------------------------------------------------------
class Sample
{
public void InstanceMethod(int x)
{
// 引数が1つだけに見えて、実は暗黙的に this を受け取っている
}
C# 基礎_デリゲート
関数指向について
---------------------------------------------------------------
関数(function)中心の設計
メソッドをオブジェクトとして扱う → デリゲート
デリゲートが有用な場面 → イベント駆動、高階関数、非同期処理
純粋な関数(pure function)
フィールド等を参照せず、同じ入力に対して常に同じ出力を返す関数
---------------------------------------------------------------
■ デリゲート
デリゲートとは、メソッドを参照するための型。
デ李ゲートは、述語やイベントハンドラ等に利用する。
インスタンスメソッドを参照したり、複数メソッドを同時に参照することができる
delegate(委譲):
「他のメソッドに処理を丸投げするためのオブジェクト」というような意味。
イベントが起きたときのイベントハンドリングをどのメソッドに丸投げ(委託)するかを
指示するためなどに使われる。
デリゲートの定義について
delegateを使用するには、まず、
delegate 戻り値の型 デリゲート型名(引数リスト);
特徴:
・定義したデリゲート型は、ユーザ定義のクラスや構造体と同じ1つの型として扱われる。
・デリゲート型は自動的にSystem,Delegateクラスの派生クラスになる。
C#のデリゲートの利点:
◇ インスタンスメソッドの代入が可能
◇ 複数のメソッドを代入できる
◇ 非同期呼び出し
◇インスタンスメソッドの代入
・クラス(static)メソッドとインスタンス(非static)メソッドの
どちらでも代入することが出来る。
◇複数のメソッドを代入する際
+=演算子を用意いることで、複数のメソッドを代入することができる。
→複数のメソッドを代入した状態で、デリゲート呼び出しを行うと、
代入した全てのメソッドが呼び出される。
複数のメソッドを格納した状態のデリゲートのことを「マルチキャストデリゲート」
と呼ぶ。
※ マルチキャストデリゲートの呼び出しは、+=で代入した順に逐次実行される。
◇ 非同期呼び出し
非同期呼び出し(Asynchronous Call)とは
メソッドを呼び出した瞬間に呼び出し元に処理が戻ってくるような呼び出しのこと。
メソッドを呼び出しをすると、デリゲートを介して呼び出されるメソッドの処理と、
呼び出し元の処理が並行して行われることになる。(マルチスレッド)
デリゲート型を定義すると、C#コンパイラによって自動的にBeginInvokeとEndInvoke
というメソッドが生成される。
BeginInbokeを用いることで、非同期呼び出しを開始し、EndInvokeを用いることにより、
非同期処理が終了を待つことができる。
BeginInvokeの処理:流れ
デリゲート型の定義時に引数リストで指定した引数と、System.AsyncCallbackデリゲート型の
引数およびobject型の引数をとり、System.IAsyncResultインターフェース型の値を返す。
EndInvokeの処理:流れ
デリゲート型の定義時にrefまたはoutキーワードを付けた引数およびSystem.IAsyncResult
インターフェースの引数を持ち、デリゲートの戻り値と同じ型の戻り値を持つ。
■ デリゲートの用途
プログラミングの世界での述語の定義
あるオブジェクトxが「xは○○である」という条件を満たすかどうか
調べるメソッドのことをいう。
例題:
static int Select(int x)
{
int n=0;
foreach(int i in x) if(i > 10) ++n;
int y = new int[n];
n=0;
foreach(int i in x)
if(i > 10)
{
y[n] = i;
++n;
}
return y;
}
例題を述語使って実装:
delegate bool Predicate(int n);
tatic int Select(int x, Predicate pred)
{
int n=0;
foreach(int i in x)
if(pred(i)) ++n;
int y = new int[n];
n=0;
foreach(int i in x)
if(pred(i))
{
y[n] = i;
++n;
}
return y;
}
例題に述語を使って、使用する際の例:
using System;
delegate bool Predicate(int n);
class DelegateTest
{
static void Main()
{
int x = new int{1, 8, 4, 11, 8, 15, 12, 19};
// x の中から値が 10 以上のもだけ取り出す
int y = Select(x, new Predicate(IsOver10));
foreach(int i in y)
Console.Write("{0} ", i);
Console.Write("\n");
// x の中から値が (5, 15) の範囲にあるものだけ取り出す
int z = Select(x, new Predicate(Is5to15));
foreach(int i in z)
Console.Write("{0} ", i);
Console.Write("\n");
}
static bool IsOver10(int n){return n > 10;}
static bool Is5to15(int n){return (n > 5) && (n < 15);}
/// <summary>
/// x の中から条件 pred を満たすものだけを取り出す。
/// </summary>
/// <param name="x">対象となる配列</param>
/// <param name="pred">述語</param>
/// <returns>条件を満たすものだけを取り出した配列</returns>
static int Select(int x, Predicate pred)
{
int n=0;
foreach(int i in x)
if(pred(i)) ++n;
int y = new int[n];
n=0;
foreach(int i in x)
if(pred(i))
{
y[n] = i;
++n;
}
return y;
}
}
■ 匿名関数
匿名関数には、C#2.0とC#3.0で導入された2つのパターンがある。
・匿名メソッド式
・ラムダ式
匿名メソッド式は概念のみ
現在使用されているのは、ラムダ式が多い。
◇匿名メソッドとは、
delegateキーワードから始まり、メソッドの中身を任意の箇所に埋め込んだ
部分のことをいう。
◇ラムダ式
・ラムダ式とは
関数(メソッド)を整数などの変数と全く同列に扱う手法のこと。
・匿名関数としても使えるもの、式木を作れる。
匿名メソッド式からラムダ式への移り変わり方
--------------------------------------------------------------
delegate(int n){ return n > 10; }
--------------------------------------------------------------
※C#2.0バージョン(匿名メソッド式)
↓
--------------------------------------------------------------
(int n) => { return n > 10; }
--------------------------------------------------------------
※C#3.0バージョン(ラムダ式)
delegateキーワードが省略されている
↓
--------------------------------------------------------------
Func<int,bool> f = n => { return n > 10; };
--------------------------------------------------------------
※C#3.0バージョン(ラムダ式)
変数の型が左辺値や関数の引数から推論できる場合には簡素化できて、
省略ができる。
(int n)の型を省略
Func(int,bool)には、デリゲートのPredicateクラスにより、
Func(T,bool)型であるため、Func(T,bool)のTが(int x)と分かっていることから
省略が可能となっている。
↓
--------------------------------------------------------------
Func<int,bool> f = n => n > 10;
--------------------------------------------------------------
※C#3.0バージョン(ラムダ式)
ラムダ式の中身がreturn文1つだけの場合
{ }やreturnも省略できる。
省略前
--------------------------------------------------------------
Func<int,bool> f = delegate(int n){ return n > 10; };
--------------------------------------------------------------
上と下のコードは同じ意味になる。
省略後
--------------------------------------------------------------
Func<int,bool> f = n => n > 10;
--------------------------------------------------------------
使える既存デリゲートメソッド
・MehtodInvokerデリゲート(System.Windows.Forms名前空間)
・Actionデリゲート(System名前空間)
・Action<T>ジェネリック・デリゲート(System名前空間)
・Action<T1,T2>ジェネリック・デリゲート(System名前空間)
・Action<T1,T2,T3>ジェネリック・デリゲート(System名前空間)
・Action<T1,T2,T3,T4>ジェネリック・デリゲート(System名前空間)
・Predicate<T>ジェネリック・デリゲート(System名前空間)
・Func<TResult>ジェネリック・デリゲート(System名前空間)
・Func<T,TResult>ジェネリック・デリゲート(System名前空間)
・Func<T1,T2,TResult>ジェネリック・デリゲート(System名前空間)
・Func<T1,T2,T3,TResult>ジェネリック・デリゲート(System名前空間)
・Func<T1,T2,T3,T4,TResult>ジェネリック・デリゲート(System名前空間)
URL:参考
https://www.atmarkit.co.jp/fdotnet/csharp30/csharp30_02/csharp30_02_02.html
■ covariance(共変性)と contravariance(反変性)
・covariance
基底クラスを戻り値とするデリゲートに対して、
派生クラスを戻り値とするメソッドを代入できること。
例:
class Base { }
class Derived : Base { }
delegate Base DelegateBaseReturn();
class Program
{
static void Main(string args)
{
Base xb;
xb = BaseReturn(); // 型が完全一致
xb = DerivedReturn(); // 基底クラスへのキャストは合法
DelegateBaseReturn db;
db = BaseReturn; // 型が完全に一致
db += DerivedReturn; // 戻り値の型が違うけど、これもok
xb = db();
}
static Base BaseReturn() { return new Base(); }
static Derived DerivedReturn() { return new Derived(); }
}
(考察)
delegate Base DelegateBaseReturn();が入ったdbに対して、
static Derived DerivedReturn() { return new Derived(); }
が派生クラス(Derived)であるため、戻り値が違っても代入可能になっている。
・contravariance
派生クラスを引数とするデリゲートに対して、基底クラスを引数とするデリゲートを
代入できること。
例:
class Base { }
class Derived : Base { }
delegate void DelegateDerivedParameter(Derived x);
class Program
{
static void Main(string[] args)
{
Derived xd = new Derived();
DerivedParameter(xd); // 型が完全一致
BaseParameter(xd); // 基底クラスへのキャストは合法
DelegateDerivedParameter dd;
dd = DerivedParameter; // 型が完全一致
dd += BaseParameter; // 引数の型が違うけど、これもok
}
static void BaseParameter(Base x) { }
static void DerivedParameter(Derived x) { }
}
(考察)
DelegateDerivedParameter(Derived x)とDerivedParameter(Derived x)は一緒だが、
BaseParameter(Base x)のように引数の型が違う場合でも、
派生クラスの引数に基底クラスは入れられる。
iPhoneアプリ開発_知識
iPhoneアプリ開発で準備するもの
・Mac
・Xcode
・AppleのDeveloper登録が必要で年間11,800円
Appleにアプリをリリースするには
AppStoreに公開するためには、
iTunesCoonnect,DeveloperCenterというサイトで設定をし申請を行う。
リリースの為には、AppleのDeveloper登録が必要で年間11,800円かかる。
iPhoneアプリで収益を上げるためには、
・有料ダウンロード
・広告
・アプリ内課金
有料アプリは、ゲームが多く購入される傾向に。
=ゲームアプリで多くの人に認知される必要がある。
広告は、アプリ内に広告を表示して収益を得る。
アプリ自体は無料で使い、広告を出すことで収益が上がる。
=多くの人にダウンロードしてもらう。
アプリ内課金はゲームによく使われる。
=ゲームアプリのクオリティ重視、面白いと思ってもらう人を一定数
Androidアプリ開発_知識
Androidアプリ開発で必要なもの
・パソコン(Mac/Windows/Linuxのいずれか)
・AndroidStuido,Eclipseという環境
・java
・Googleアカウントをデベロッパーとして登録する料金($25=3000円ほど)
Androidアプリを作ろうと思ったら
「企画→設計→開発」といった流れが一般的
個人で作るアプリであれば、アイデアが細かく決まっている必要はない。
作りながら、こういう機能が欲しいなどと思い浮かぶ。
・どんなアプリか
・誰がそのアプリを使うのか
・どんな機能、どんな画面が必要か
・(収益を得るならば)どこで収益を得るのか
など。
アプリをリリースしたい
Androidアプリをリリースするには、Google Playで公開することが一般的
アプリを公開するには、Google Playデベロッパーコンソールと公開用コンソールというものを
活用してリリースする。また、
それらを使用するためにGoogleアカウントをデベロッパーとして登録する必要がある。
登録料:$25(一度支払えば年数関係なく使用可能)支払う必要がある。
RFP(提案依頼書)、RFI(情報提供依頼書)とは
■RFP(提案依頼書)とは
依頼先に求める要件を明確に記載した書類のこと。
自社が求めている要望を明確にして、文章で相手に伝えるツール。
できる。
・各社に同じ内容を伝えますので、提示される提案書の内容も均一化されやすくなり、
各社ごとの評価をつけやすくなる。
・RFPを作成する時点で、システムの目的や必要な条件を整理しやすくなります。社内の関係部署に
システムの必要性を伝えやすくなる。
・開発する目的
・目指す目標・成果
・予算
・スケジュール
など
複数の企業や部署間で話題を共有するのに必要です。
提案を求める理由を明確にします。
管理システムがほしいなど「○○のために、■■がほしい」という内容です。
システムを導入することで得られる効果を明確にします。
顧客に付加価値を与えるなどです。具体的な数値があるほうが、
提案者側もより詳細な提案が可能になります。
選定期間、開発期間、導入予定日など、現時点で決まっていることも記載しましょう。
最低限の情報に加えて・・・
・納品する品物
・必ず満たすシステム条件
・開発企業に期待していること
・開発者のメンバー名や体制
など
要件はどの範囲までなのか、誰が何を担当するのか、なども
記載したほうが良い提案を受けられます。
要望がまったく反映できていない提案になることがある。
優先事項が未決定などの情報は、依頼先に伝えること。
参考資料を記載するほうが要望の理解が深まります。
自社のホームページや過去製品と似た形にしてほしいなど、要望は詳細に記載する。
必要条件以外でも、要望に寄り添った良い提案がもらえるようになる。
依頼先のこれまでの実績や取り扱っている商品の参考価格、基本価格、グループ子会社などの請求
する「情報提供依頼書」のこと。
・自社が求めていることが実現可能な製品やサービスを扱っている企業か確認することができる。
開発依頼がzン帝の情報提供という旨をRFIで伝えれば、
これから行う開発に沿った形の情報や提案を相手側から引き出すことも可能。
インターフェース_ジェネリック_メモ
インターフェースは、コストが高いため、利用されにくいが、
問題にならないケースとして、
フィールドのメモリを持っていなければ、問題ない。
抽象メソッドだけを持つクラスを作ることは推奨されている。
インターフェースは仲介役です。
クラスが実装すべき規約(どういうメソッドにどういう引数を渡すかなど)を定めるもの。
クラス設計者とクラス利用者の空いたの仲介役を担うのがインターフェース。
ジェネリックを使う利点
・直行性が高いこと
コンテナクラは、格納する要素の型、格納する方式によって、さまざまな種類があり、
配列、検索、置換などのさまざまな操作が考えられる。
※コンテナクラスとは
複数の値を一まとめにして管理するクラスのこと
通常:
格納する型の種類がi個、格納方式の数がj個、操作の数がk個あるとき、
全部で、i×j×k個のコードを書く必要がある。
格納する型、格納方式、捜査に依存性がないため、
i+j+k個という少ないコードで書ける。