SlideShare uma empresa Scribd logo
1 de 153
Baixar para ler offline
 
UnityでC#を学び始めた私の主張
 
@RyotaMurohoshi
2015/09/26(土)*Comm*Tech*Fes4val
はじめまして、こんにちは
Unityセッションを担当させていただきます
@RyotaMurohoshi-と申します
ごめんなさい
UnityにおけるC#とか.NETの
『なんかすんげぇこと』は話しません
(話せません。ごめんなさい)
お前だれよ
• twi%er(:(@RyotaMurohoshi
• 投稿先(:(h%p://qiita.com/RyotaMurohoshi
• 所属(:(Fuller,(Inc.
• コミュニティ(:(Unity部
• その他(:(UniLinqっての作りました(いらない子になりました)
「UnityでC#を学び始めた私の主張」のタイトル通り、
ゲームエンジンUnityとの出会い、C#を触り始めました
今は業務でもUnityでゲームを作っています
今日のこのセッションの方向性と目的を
ちょっとお話させて下さい
以前こんなことがありました
あるUnityの勉強会の飛び入りLTにて
おれ:「LINQ知っている方∼(みなさんしってるよねー)」
会場:「しーん。。。」
おれ:(大体一割くらいだと。。。)
おれ:(LINQを使わないとはもったいない!!!)
※ただし、プログラマのみが対象の勉強会ではないです
※当時は、LINQがiOSで落ちるとか問題もあった
デリゲートやラムダ式についてまとめ記事書いた際も
「わかってなかった」とか「これ、知らなかった」
とかという感想をいただきました。
【LINQの前に】ラムダ式?デリゲート?Func<T,,TResult>?な人へのまとめ【知ってほしい】
Unityやっている人の中には
C#のあれこれ
実は知らない人も以外といるのでは?
確かにインターフェースの明示的な実装や
型パラメータの制約とか知らなくても
ゲームが作れなくはないですが...
だからって
知らなくていいわけでは
ないと思うんですよ
今日はUnityを題材に
普段のUnityの勉強会では触れられることが少ない
C#の言語機能を紹介し、個人的な主張を行います
みなさんへのお願い!
知らなかったことがあった方へ
「ここ知らなかった」とか「ここためになった」
 ってつぶやいてくれると嬉しいです
C#マスターなみなさんへ
今日の内容はみなさんには当たり前のことばかりだと思います
!どうか私の意見に、ツッコミや反論お願いします!
どんどんつぶやいてください
後日、みなさんのご意見やツッコミを参考にさせていただいて
別のブログとかでUnityコミュ二ティーに歓迎できたら最高!
(できたらいいな...)
#comuplus)#roomD
つけてどんどんつぶやいてくれると嬉しいです
まえおき終わり
本セッションの内容・意見は登壇者が所属する
企業・ユーザーグループの意見ではなく
登壇者個人のものです
【主張】
【主張】
インターフェースの明示的な実装を
状況に応じて使おう
IDragHandler
void%OnDrag(PointerEventData)というメソッドをもつ
ドラッグ検知に関連するUnityのインターフェース
これを例にまず紹介します
IDragHandlerを『普通に』実装する例
using UnityEngine;
using UnityEngine.EventSystems;
public class DragSample : MonoBehaviour, IDragHandler {
public void OnDrag(PointerEventData pointerData {
Debug.Log ("OnDrag");
}
}
IDragHandlerを『明示的に』実装する例
using UnityEngine;
using UnityEngine.EventSystems;
public class DragSample : MonoBehaviour, IDragHandler {
// publicがなくなってメソッド名にインターフェース名「IDragHandler.」がついた
void IDragHandler.OnDrag(PointerEventData pointerData) {
Debug.Log ("OnDrag");
}
}
違いは?
インターフェースを普通に実装した場合
// DragSample型の変数でもOnDragメソッドが呼べる
// dragSampleはDragSample型
dragSample.OnDrag(pointerData);
インターフェースを明示的に実装した場合
// DragSample型の変数ではOnDragメソッドが呼べない
// dragSample.OnDrag(pointerData); 左はコンパイルエラー
// IDragHandler型の変数に代入すれば呼べる
IDragHandler handler = dragSample;
handler.OnDrag(pointerData);
嬉しいのか?
自分は嬉しいと思う!
インターフェースの明示的な実装をしたメソッドは
その型の変数経由で『呼べなくなってしまう』
ではなくて、
『呼ばせたくない場合に、呼べなくすることができる!』
だと思う
例1
List<T>はICollec.on<T>.IsReadOnlyを明示的な実装している
例1
List<int> numList = new List<int> {0, 1, 2, 3};
// 下記はコンパイルエラー
//bool isReadOnly = numList.IsReadOnly;
// ICollection<int> 経由では呼び出せる
ICollection<int> numCollection = numList;
bool isReadOnly = numCollection.IsReadOnly;
例1
List<T>はICollec.on<T>.IsReadOnlyを明示的な実装をしている
ICollec'on<T>型の変数では有用なプロパティだけど、
List<T>の変数では呼べないほうが嬉しい
(List<T>型ならば定義的falseなのは当たり前だから、IList.IsFixedSizeも同様)
例2
ReadOnlyCollec,on<T>の
ICollec'on<T>.ClearやICollec'on<T>.Addなど明示的な実装
ReadOnlyなんだから、要素操作はさせたくない。呼ばせたくない。
ICollec'on<T>型などの変数に入れて呼んでしまった場合、NotSupportedExcep'onを投げる
例3
ISerializableを実装するクラスのGetObjectDataメソッド
GetObjectDataメソッドは、シリアル化インフラストラクチャが呼び出すもので、
他のユーザー定義クラス内などで、実装したクラスの変数を介して呼ぶものではないため
h"ps://msdn.microso/.com/ja2jp/library/ms229034(v=vs.100).aspxAより
ではさっきのUnityの例に戻って
下記のOnDragは、UnityのUIイベントシステムが呼んでくれる
public class DragSample : MonoBehaviour, IDragHandler {
void IDragHandler.OnDrag(PointerEventData pointerData) {
Debug.Log ("OnDrag");
}
}
ポイントは、OnDragメソッドをイベントシステム以外から
呼ばせたいのかどうかだと思う
UnityのUIイベントシステムが呼んでくれる
ていうかむしろ他から呼ばせたくない、限定したい
なら、インターフェースの明示的な実装をした方が良くない?
という主張
もちろんOnDragメソッドをシステム以外から、
他のクラスなどから呼び出す必要があるならば別
【主張】
インターフェースの明示的な実装を
状況に応じて使おう
どう思います?ご意見募集!
「積極的な理由がない場合は、インターフェイス!メンバーの明示的な実装を避けます」@MSDNだけど
別な話ですがインターフェースの明示的な実装、よくある説明だと
「二つのインターフェースのメソッドの引数と名前が同じ時、これを使えば大丈夫ー」
という紹介が多いのですが、「List<T>のIsReadOnly」とか
「共変戻り値型がないから明示的な実装が役立つ」とかの方が
大切さが・有用さが伝わると思うのは自分だけ?
【主張】
ObjectとObject
なぜその名前にしたの?
Objectクラス
Objectクラス
• System.Objectクラス
• .NET0Framework0の全クラスの基本クラスで、型階層のルート
• キーワード「object」、でクラス名を表せる
Objectクラス
Objectクラス
• UnityEngine.Objectクラス
• Unityで重要なGameObjectやComponentの親クラス
• なんでそんな名前つけちゃったのまじで!?
Debug.Logというログを吐くメソッド
public static void Log(object message, Object context);
さー、どっちがどっちだ?
Debug.Logというログを吐くメソッド
public static void Log(object message, Object context);
第一引数がSystem.Objectで、第二引数がUnityEngine.Objectで
紛らわしいったらありゃしない
【主張】
【主張】
クラス名のかぶりをusingエイリアスディレクティブで
いいかんじにする(?)
using UnityEngine;
public class Sample : MonoBehaviour{
void Start () {
// 下記はUnityEngine.Object型
Object unityEngineObject;
// 下記はSystem.Object型
object systemObject;
}
}
using UnityEngine;
using System; // <- new!
public class Sample : MonoBehaviour{
void Start () {
// コンパイルエラー
// 下記はSystem.ObjectかUnityEngine.Objectか曖昧
// Object ambiguousObject;
// 下記はSystem.Object型
object systemObject;
}
}
ここでusingエイリアスディレクティブを使ってみる
usingエイリアスディレクティブ
名前空間または型のエイリアスを作成できる機能
using UnityEngine;
using System;
using UnityObject = UnityEngine.Object; // <- usingエイリアスディレクティブ
public class Sample : MonoBehaviour{
void Start () {
// 下記はUnityEngine.Object
UnityObject unityEngineObject;
// 下記はSystem.Object型
object systemObject;
// 残念ながら、Objectは曖昧なままでコンパイルエラー
// Object ambiguousObject;
}
}
うーん。正直、微妙!
実はあんまりUnityEngine.Object型、コードで書かないし
ドキュメントで読む時は多いから、このかぶりマジで混乱するからつらい
もう一例
System.RandomとUnityEngine.Random
UnityEngine.Randomにエイリアスを
ありっちゃありかな?
using UnityEngine;
using System;
using UnityRandom = UnityEngine.Random;
public class Sample : MonoBehaviour{
void Start () {
float randomValue = UnityRandom.value;
}
}
【主張】
クラス名のかぶりをのusingエイリアスディレクティブで
いいかんじにする(?)
のは、Objectは微妙だけれどもRandomはありっちゃありかも(個人の感想です)
【意見募集】
先ほどの二つの例、どう思われますか?
「こんなのもいいよ」とかあれば教えてください!
【主張】
【主張】
FindObjectOfType<T>でコンパイルエラー?
型パラメータの制約だぜ!
UnityEngine.Object.FindObjectOfType<T>メソッド
型を指定して、ゲームシーン中のその型のオブジェトを取得できる
// GameManagerは自作のクラスで、MonoBehaviourを継承している
GameManager gameManager = FindObjectOfType<GameManager> ();
gameManager.StartGameLoop ();
GameManager以外のクラスからでも、GameManagerのオブジェクトを取得できる
次のコードはすべてコンパイルエラー
string str = FindObjectOfType<string> ();
// MyClassは自作クラス、UnityEngine.Objectを継承していない
MyClass myClass = FindObjectOfType<MyClass> ();
// ISampleは自作インターフェース
ISample sample = FindObjectOfType<ISample> ();
なぜか?
FindObjectOfType<T>は
UnityEngine.Object型に型パラメータの制約がかかっているため
TはUnityEngine.Objectかそのサブクラスでないといけない
型パラメータの制約を使うとジェネリックなクラスやメソッドに、
型引数に指定・使用できる型の種類に制限を加えることができる
ところで先ほどのGameManagerはMonoBehaviourを継承しているので
継承階層を るとUnityEngine.Objectを継承している
自作クラスだけでなく、ビルドインの剛体運動をつかさどるRigidBodyなどいろいろ取得できる
// GameManagerは自作のクラスで、MonoBehaviourを継承している
GameManager gameManager = FindObjectOfType<GameManager> ();
gameManager.StartGameLoop ();
しかしstringやMyClass(UnityEngine.Objectを継承していない)はコンパイルエラーになる!
下記はコンパイルエラー
FindObjectsOfType<T>もUnityEngine.Objectで型パラメータの制約がされている
これだとTには、UnityEngine.Object・そのサブクラス以外が来る可能性がある
public class Utility {
// T型でゲームオブジェクトの名前がnameなものを取得
public static T[] FindObjectsOfType<T> (string name) {
return Object.FindObjectsOfType<T> ()
.Where (it => it.name == name)
.ToArray ();
}
}
下記はOK
UnityEngine.Objectで型パラメータの制約がされているので
Tには、UnityEngine.Objectかそのサブクラスしかこない
public class Utility {
// T型でゲームオブジェクトの名前がnameなものを取得
public static T[] FindObjectsOfType<T> (string name)
where T : UnityEngine.Object {
return Object.FindObjectsOfType<T> ()
.Where (it => it.name == name)
.ToArray ();
}
}
下記はコンパイルエラー
Genericなメソッド内で型パラメータの制約をTに行わないと
T型のインスタンスはSystem.Objectのメソッドしか呼べない
static T Min<T>(T a, T b) {
return a.CompareTo(b) < 0 ? a : b;
}
下記はOK
TはIComparableに制約されているので、
IComparableがもつCompareToを呼べる
static T Min<T>(T a, T b) {
where T : IComparable
return a.CompareTo(b) < 0 ? a : b;
}
型パラメータの制約、大切!
【ぼやき】
FindObjectOfType<T>の型パラメータの制約について、
Unityのドキュメントに載ってないorz
というかこのオーバーロード自体が載ってない
【ぼやき】
GetComponent<T>というよく使うメソッド
以前はTに対してComponentクラスで制約がかかっていました
けど仕様が変わっていたorz
今も前もドキュメントに記載なし、バージョンによる違いの記載ももちろんなしorz
つらたん
【意見募集】
型パラメータの制約、
こんなライブラリでこんな風に使っていて面白いぞ!
とかあったら教えてください
【主張】
【主張】
演算子のオーバーロードや型変換演算子が
裏側で使われていることを理解しよう
演算子のオーバーロード
ユーザー定義型でも+や"などの演算子が使えるようになるやつ
演算子のオーバーロードといえば
DateTime型とTimeSpan型の+と,オペレータですが
(ですよね?もっといい例あったら教えてください。)
DateTime dateTime = DateTime.Now + TimeSpan.FromSeconds (30.0);
TimeSpan duration = DateTime.Now - GetStartedTime ();
Unityでも大活躍
位置等をあらわすVector3や回転を表すQuaternionで
演算子のオーバーロードが定義されている
// Quaternionは四元数。回転・姿勢等で使う
Quaternion rotation = Quaternion.Euler (0, 0, 90.0F);
Vector3 vectorA = new Vector3 (1.0F, 1.0F, 0.0F);
Vector3 vectorB = new Vector3 (1.0F, -1.0F, 0.0F);
Vector3 addedVector = vectorA + vectorB;
Vector3 scaledVector = 2.0F * vectorA;
Vector3 rotatedVector = rotation * vectorB;
書籍・ウェブサイトでも乱用禁止と紹介されているこの機能
新たに自作クラスで定義するならしっかりじっくり考えて
覚悟を持ってやるべきだと自分は思います
型変換演算子
明示的に型を指定すれば型変換を行える明示的型変換と
型を指定しなくても必要になったら変換してくれる暗黙的型変換
型変換演算子といえば
System.Decimal型ですよね?
// 多くの数値型から暗黙的型変換
decimal num1 = 1;
decimal num2 = 2.0F;
decimal num3 = 3.0;
// 多くの数値型への明示的型変換
int numA = (int)num1;
float numB = (float)num2;
double numC = (double)num3;
Unityでも結構使われている
Color構造体からColor32構造体への暗黙的型変換
Color構造体は色を表し各成分は[0.0F,1.0F]、Color32構造体も色を表し各成分はbyte型
デザイナーから色の成分を整数でもらった時、Color32構造体は各成分をそのままかける
// 初期化が楽なColor32構造体で初期化して
// 暗黙的型変換をでよく使うColorに変換
Color color = new Color32(255, 128, 255, 255);
コード中で色を定義することが多いなら結構便利だと思う
Vector3構造体からVector2構造体への暗黙的型変換
// z座標は無視される
Vector2 vector2d = new Vector3 (1.0F, 1.0F, 0.0F);
// z座標は0.0Fが挿入される
Vector3 vector3d = new Vector2 (1.0F, 1.0F);
結構便利!だと思う。自分は。
UnityEngine.Objectからboolへの型変換
// Rigidbodyは継承階層を るとUnityEngine.Objectにたどり着く
Rigidbody rigidbody = GetComponent<Rigidbody>();
// 下記はif (rigidbody != null) { と実質同じらしい
if (rigidbody) {
rigidbody.AddForce(10.0F * Vector3.forward);
}
これは便利っちゃ便利だと思うかもしれないけれど、
そんなにうれしくない。どう思います?
【主張】
演算子のオーバーロードや型変換演算子が
裏側で使われていることを理解しよう
自分で無計画に定義するのは良くないと思うけれど、裏側でどうなっているのか把握するのは大切!
(あとVector3の==とかも大事)
【主張】
【主張】
var禁止とか言わないでお願い!var使おうぜ!
var好きです!var良くないですか?
Unityでも大活躍
// 右辺でRigidbody型って書いてあるじゃん!
// Rigidbody rigidbody = GetComponent<Rigidbody> ();
var rigidbody = GetComponent<Rigidbody> ();
// 右辺でGameManager型って書いてあるじゃん!
// GameManager gameManager = FindObjectOfType<GameManager> ();
var gameManager = FindObjectOfType<GameManager> ();
適材適所でvarを使う
// 戻り値型が伝わりズラい・自明でないメソッドでvar使おうとは言わない
// var ambiguousTypeObject = GetAmbiguousTypeObject ():
// こういう場合、はっきり型を明示したほうがいいと思う
SampleType ambiguousTypeObject = GetAmibigaousTypeObject ():
// でも右辺から型が自明ならvar使ったほうがすっきりする!
// Dictionary<string, List<LongLongTypeName>> dictionary
// = new Dictionary<string, List<LongLongTypeName>> ();
var dictionary = new Dictionary<string, List<LongLongTypeName>> ();
悲しいかな
『var使うな』、『var使いたくない』という方がたまにいるorz
var使いたくない人の主張1
「型がないの気持ち悪いじゃん」
「型がないの気持ち悪いじゃん」への反論
型がないのではなくて、暗黙的に型が指定されているだけ
var使いたくない人の主張2
「型書いてないと分かりずらくない?」
「型書いてないと分かりずらくない?」への反論
無理にvar使うと分かりズラいときもあるから、
そういう時は使わなくてもいいと思う
けど明らかにわかる時は禁止する理由にはならないと思う!
var使いたくない人の主張3
「List<string>をIList<string>変数に入れたいけれど、
varはList<string>型になるじゃん」
「List<string>をIList<string>変数に入れたいけれど、varはList<string>型になるじゃん」への反論1
メソッドの返り値等で、適切な抽象的な型を返すの大事だよね!
けどvarはメソッドローカルスコープ限定だし影響範囲は
そんな大きくないよね?ローカルスコープではList<T>でもよくね?
まさかとは思うけれど100行1000行なメソッド書かないよね?
「List<string>をIList<string>変数に入れたいけれど、varはList<string>型になるじゃん」への反論2
IList<string>に入れたいっていうけれど、
本当にIList<string>で扱いたいの?
string[]もIList<string>実装しているんだけれど?
【意見募集】
var禁止って言われた時のいい感じの反論
【主張】
【主張】
省略可能な引数(オプション引数)、便利!
けれど個人的にはデフォルト引数って言わないでほしい!
省略可能な引数(オプション引数)がなんなのかは割愛
個人的にはデフォルト引数って言わないでほしい!
C++ではデフォルト引数っていうんですよね?
けれどC#では省略可能な引数(オプション引数)なんだから、C#の言葉を使った方がいいと思う
別にC++をディスる意図は全くないです
「Javaだとこう言う」「C++だとこう言う」ではなくて
郷に入っては郷に従え、C#の言葉を使った方がいいと思う
他の言語の流儀を入れるときは中途半端にやらず、しっかり徹底的にやるべきだと思う
【主張】
【主張】
名前付き引数便利!
メソッド定義するときは引数名も大切に!
名前付き引数がなんなのかは割愛
以前こんな辛いことがありました
UniLinqというライブラリをつくっていた際気づいた。
LINQのCountメソッド、Func<TSource,2Boolean>型のデリゲートの引数名は
正しくは、『predicate』なのだけれど!
// 下記はコンパイルエラー
// int count = numList.Count(predicate: num => num > 90);
// 引数名が仕様と違う
int count = numList.Count(selector: num => num > 90);
Unityが使っている古いmonoが間違っていたorz
つらい
名前付き引数があるC#では
引数名を変えると破壊的な変更になるし
適当な引数名つけちゃダメ
【主張】
【主張】
型の規定値を理解して
変なバグを回避しようぜ
次のコードは問題がある
FirstOrDefaultは、引数のデリゲートが表す条件を満たす最初の要素を取得する
『満たす要素がなかった場合』がここでのポイント
Vector3 playerPosition = GetPlayerPosition();
List<Vector3> enemyPositions = LoadEnemyPositions();
float attakRange = 5.0F;
Vector3 targetEnemyPosition = enemyPositions
.FirstOrDefault(p => Vector3.Distance(playerPosition, p) <= attakRange);
満たす要素がなかった場合、FirstOrDefaultは型の規定値を返す!
nullを返すというのは間違い!FirstOrNullじゃないし
nullは参照型の規定値で、値型の規定値はnullじゃない
型の規定値
• 参照型はnull
• 構造体はすべてのメンバを規定値で初期化したもの
• intは0
• floatは0.0F
• boolはfalse
(略)
Vector3は構造体なので規定値は
全部のメンバを規定値で初期化したもの
(x,$y,$zがすべて0なもの)
条件を満たす要素が存在しなかった場合
targetEnemyPosi.onはnew0Vector3(0.0F,00.0F,00.0F)という結果になる。(nullではない)
Vector3 playerPosition = GetPlayerPosition();
List<Vector3> enemyPositions = LoadEnemyPositions();
float attakRange = 5.0F;
Vector3 targetEnemyPosition = enemyPositions
.FirstOrDefault(p => Vector3.Distance(playerPosition, p) <= attakRange);
 『正しい値が入っていると思ったら、実は規定値が入っていたためバグ!』に気をよう
【主張】
【主張】
List<T>の代わりに
ReadOnlyCollec,on<T>を検討しよう
(例)
PlayerクラスはList<Item>型のItemsプロパティを持つ
このItemsをクラス外部に公開したい
けど中身の書き換えなどはクラス外部でされたくない
こうすれば安心?
public class Player
{
/*略*/
public List<Item> Items { get; private set; }
}
ではない!
ダメな例
Player player = GetPlayer();
// これはできないけれど
// player.Items = new List<Item>();
// 普通に外部からList<T>のメソッド経由で中身をいじれる
player.Items.Clear();
ではどうする?
案1"防御的コピーをする
public class Player {
/*略*/
private List<Item> items;
public List<Item> Items { get { return new List<Item>(items); } }
}
内部のリストメンバの複製を外部に公開する
けれど、これだと「クラス内のアイテムのリストのデータはいじれなよ」「防御的コピーしたよ」
ってことがぱっと見で伝わらない。Playerクラスのコード'or'ドキュメントを読まないといけない
案2"プロパティをIEnumerable<T>型にする
public class Player {
/*略*/
private List<Item> items;
public IEnumerable<Item> Items { get { return items; } }
}
「いじれないよ」ということは伝わるけれど、「確定しているデータだよ」が伝わらない
「遅延評価される値?」「内部ではリスト・配列で保持せずDBにいちいち問い合わせてる?」
って勘違いされる可能性あり。結局Playerクラスのコードかドキュメントを読まないといけない
案3"プロパティをIReadOnlyList<T>型にする
public class Player {
/*略*/
private List<Item> items;
public IReadOnlyList<Item> Items { get { return items; } }
}
「外部からだといじれないよ」も「遅延評価じゃなくて確定しているデータだよ」も伝わる
【悲報】だけどUnityだと使えない【致命的】
.NET%4.5で登場したインターフェースだからorz
そこでReadOnlyCollec,on<T>ですよ!
ReadOnlyCollec,on<T>
指定したリストをラップする読み取り専用のラッパーで、ラップ対象の中身が変わるとこいつも変わる
IEnumerable<T>、ICollec1on<T>、IList<T>などなどを実装している。
IList<T>.Addとか要素を変更する系のメソッドはインターフェースの明示的な実装をしていて、
インターフェース型経由でそういうのを呼び出すとNotSupportedExcep-onを投げる
案4"プロパティをReadOnlyCollec.on<T>型にする
public class Player {
/*略*/
private List<Item> items;
public ReadOnlyCollection<Item> Items {
get { return new ReadOnlyCollection<Item>(items); }
}
}
もしくは、(意味は変わってくるけれど)
public class Player {
/*略*/
public ReadOnlyCollection<Item> Items { get ; private set; }
}
「外部からだといじれないよ」も
「遅延評価じゃなくて確定しているデータだよ」も伝わる
Unityでも使える(<(ここ重要)
【質問】
.NET%Framework%4.5以上が使える場合、
IReadOnlyList<T>ってがっつり使います?
【主張】
主張
Transformと子供オブジェクトの列挙とGetEnumerator
Transformクラス
ゲーム中のオブジェクトの位置・大きさ・回転を保持するクラス
オブジェクト間の親子構造も司っている
対象Transoformの子オブジェクト(のTransform)の列挙
 
// 対象の子供オブジェクトの名前を表示
foreach(Transform childTransform in transform) {
Debug.Log(childTransform.name); // 名前を表示
}
なぜこれができるのか?
List<T>や配列みたいなことができるのか?
TransformがGetEnumeratorメソッドを実装していて
それが子供オブジェクトを列挙するような仕様だからですよね。
(ダックタイピングなアレ)
まとめ
別にGetEnumerator知らなくても子要素の列挙できる
インターフェースの明示的な実装や型パラメータの制約
知らなくてもゲームは作れる
けれど知っていた方がいいと思う
困った時、いろいろ解決できる
C#らしいコードがいろいろ助けてくれると思う
プログラミング言語は道具
だからこそ適当でいいわけはなく
しっかりと使いこなしたい
ちゃんと勉強したいぜC#!
つっこみお待ちしてます
 
UnityでC#を学び始めた私の主張
 
@RyotaMurohoshi
2015/09/26(土)*Comm*Tech*Fes4val

Mais conteúdo relacionado

Mais procurados

G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)Nobuhiro Sue
 
C++0x 言語の未来を語る
C++0x 言語の未来を語るC++0x 言語の未来を語る
C++0x 言語の未来を語るAkira Takahashi
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~Fujio Kojima
 
Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説JPCERT Coordination Center
 
I phoneアプリ入門 第5回
I phoneアプリ入門 第5回I phoneアプリ入門 第5回
I phoneアプリ入門 第5回Sachiko Kajishima
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときShintarou Okada
 
shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)Cryolite
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会Akihiko Matuura
 
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)Cryolite
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーmganeko
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料gaaupp
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)Akihiko Matuura
 
Java puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanJava puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanYoshio Terada
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526 masahitojp
 
Boost.Coroutine
Boost.CoroutineBoost.Coroutine
Boost.Coroutinemelpon
 
函数プログラミングの エッセンスと考え方
函数プログラミングのエッセンスと考え方函数プログラミングのエッセンスと考え方
函数プログラミングの エッセンスと考え方啓 小笠原
 
Template Meta Programming入門から応用まで
Template Meta Programming入門から応用までTemplate Meta Programming入門から応用まで
Template Meta Programming入門から応用までyoshihikoozaki5
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 

Mais procurados (20)

G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)
 
C++0x 言語の未来を語る
C++0x 言語の未来を語るC++0x 言語の未来を語る
C++0x 言語の未来を語る
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
 
Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
I phoneアプリ入門 第5回
I phoneアプリ入門 第5回I phoneアプリ入門 第5回
I phoneアプリ入門 第5回
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
 
shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)shared_ptr & weak_ptr (ppt 第2版, DL 専用)
shared_ptr & weak_ptr (ppt 第2版, DL 専用)
 
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
 
shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)shared_ptr & weak_ptr (ppt 初版, DL 専用)
shared_ptr & weak_ptr (ppt 初版, DL 専用)
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料
 
More C++11
More C++11More C++11
More C++11
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
Java puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanJava puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta Japan
 
20170131 python3 6 PEP526
20170131 python3 6 PEP526 20170131 python3 6 PEP526
20170131 python3 6 PEP526
 
Boost.Coroutine
Boost.CoroutineBoost.Coroutine
Boost.Coroutine
 
函数プログラミングの エッセンスと考え方
函数プログラミングのエッセンスと考え方函数プログラミングのエッセンスと考え方
函数プログラミングの エッセンスと考え方
 
Template Meta Programming入門から応用まで
Template Meta Programming入門から応用までTemplate Meta Programming入門から応用まで
Template Meta Programming入門から応用まで
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 

Mais de Ryota Murohoshi

UnityでC#6.0が使える未来がそろそろ来そう!
UnityでC#6.0が使える未来がそろそろ来そう!UnityでC#6.0が使える未来がそろそろ来そう!
UnityでC#6.0が使える未来がそろそろ来そう!Ryota Murohoshi
 
【Unity】気づいたら加わっていたあいつ【もくもく】
【Unity】気づいたら加わっていたあいつ【もくもく】【Unity】気づいたら加わっていたあいつ【もくもく】
【Unity】気づいたら加わっていたあいつ【もくもく】Ryota Murohoshi
 
【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】
【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】
【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】Ryota Murohoshi
 
Javaのバージョニング問題の話しよっか
Javaのバージョニング問題の話しよっかJavaのバージョニング問題の話しよっか
Javaのバージョニング問題の話しよっかRyota Murohoshi
 
LINQ、Select連弾ってやります?
LINQ、Select連弾ってやります?LINQ、Select連弾ってやります?
LINQ、Select連弾ってやります?Ryota Murohoshi
 
C#のList_TがIListを実装している件
C#のList_TがIListを実装している件C#のList_TがIListを実装している件
C#のList_TがIListを実装している件Ryota Murohoshi
 
どうしてこのコードエラーになるんですか?
どうしてこのコードエラーになるんですか?どうしてこのコードエラーになるんですか?
どうしてこのコードエラーになるんですか?Ryota Murohoshi
 
広告ネイティブプラグインの辛かった話しよっか
広告ネイティブプラグインの辛かった話しよっか広告ネイティブプラグインの辛かった話しよっか
広告ネイティブプラグインの辛かった話しよっかRyota Murohoshi
 
普段C#を使っている僕から見たKotlin
普段C#を使っている僕から見たKotlin普段C#を使っている僕から見たKotlin
普段C#を使っている僕から見たKotlinRyota Murohoshi
 
UnityでのLINQ活用例
UnityでのLINQ活用例UnityでのLINQ活用例
UnityでのLINQ活用例Ryota Murohoshi
 
「LINQ」っていう名前だけでも 覚えて帰ってください!
「LINQ」っていう名前だけでも 覚えて帰ってください!「LINQ」っていう名前だけでも 覚えて帰ってください!
「LINQ」っていう名前だけでも 覚えて帰ってください!Ryota Murohoshi
 
JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!
JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!
JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!Ryota Murohoshi
 
RxJava初心者の私が良いと思ったやり方、素敵だと思った資料など
RxJava初心者の私が良いと思ったやり方、素敵だと思った資料などRxJava初心者の私が良いと思ったやり方、素敵だと思った資料など
RxJava初心者の私が良いと思ったやり方、素敵だと思った資料などRyota Murohoshi
 
共変戻り値型って知ってますか?
共変戻り値型って知ってますか?共変戻り値型って知ってますか?
共変戻り値型って知ってますか?Ryota Murohoshi
 
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数Ryota Murohoshi
 

Mais de Ryota Murohoshi (18)

UnityでC#6.0が使える未来がそろそろ来そう!
UnityでC#6.0が使える未来がそろそろ来そう!UnityでC#6.0が使える未来がそろそろ来そう!
UnityでC#6.0が使える未来がそろそろ来そう!
 
【Unity】気づいたら加わっていたあいつ【もくもく】
【Unity】気づいたら加わっていたあいつ【もくもく】【Unity】気づいたら加わっていたあいつ【もくもく】
【Unity】気づいたら加わっていたあいつ【もくもく】
 
【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】
【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】
【ハピバ】未来に備えたKotlin、大好きだぜ!【Kotlin 1.0】
 
「var禁止」禁止
「var禁止」禁止「var禁止」禁止
「var禁止」禁止
 
Javaのバージョニング問題の話しよっか
Javaのバージョニング問題の話しよっかJavaのバージョニング問題の話しよっか
Javaのバージョニング問題の話しよっか
 
LINQ、Select連弾ってやります?
LINQ、Select連弾ってやります?LINQ、Select連弾ってやります?
LINQ、Select連弾ってやります?
 
C#のList_TがIListを実装している件
C#のList_TがIListを実装している件C#のList_TがIListを実装している件
C#のList_TがIListを実装している件
 
どうしてこのコードエラーになるんですか?
どうしてこのコードエラーになるんですか?どうしてこのコードエラーになるんですか?
どうしてこのコードエラーになるんですか?
 
広告ネイティブプラグインの辛かった話しよっか
広告ネイティブプラグインの辛かった話しよっか広告ネイティブプラグインの辛かった話しよっか
広告ネイティブプラグインの辛かった話しよっか
 
普段C#を使っている僕から見たKotlin
普段C#を使っている僕から見たKotlin普段C#を使っている僕から見たKotlin
普段C#を使っている僕から見たKotlin
 
T4使ってみた
T4使ってみたT4使ってみた
T4使ってみた
 
UnityでのLINQ活用例
UnityでのLINQ活用例UnityでのLINQ活用例
UnityでのLINQ活用例
 
私とUnityとLINQと
私とUnityとLINQと私とUnityとLINQと
私とUnityとLINQと
 
「LINQ」っていう名前だけでも 覚えて帰ってください!
「LINQ」っていう名前だけでも 覚えて帰ってください!「LINQ」っていう名前だけでも 覚えて帰ってください!
「LINQ」っていう名前だけでも 覚えて帰ってください!
 
JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!
JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!
JXUGのLTだけれどもUnity+iOS+LINQの話をしようと思う!
 
RxJava初心者の私が良いと思ったやり方、素敵だと思った資料など
RxJava初心者の私が良いと思ったやり方、素敵だと思った資料などRxJava初心者の私が良いと思ったやり方、素敵だと思った資料など
RxJava初心者の私が良いと思ったやり方、素敵だと思った資料など
 
共変戻り値型って知ってますか?
共変戻り値型って知ってますか?共変戻り値型って知ってますか?
共変戻り値型って知ってますか?
 
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数
明日からちょっと KotlinでAndroidが書きたくなる(かもしれない?)SAM変換と拡張関数
 

UnityでC#を勉強しはじめた私の主張