ページ 1 / 1
このコードの意味を教えてください。
Posted: 2014年3月24日(月) 22:03
by シャープ*
お疲れ様でございます。
初歩的な質問で申し訳ございませんが、以下に示すコードの意味を教えていただけますでしょうか。
コード:
class Observer<T> : IObserver<T>
{
private readonly Action onCompleted = null;
//(以下続く)
1行目の、classの後は何をしているところですか?
3行目の、Actionには<>でくくった型名を指定しなくてもよいのでしょうか。
転載元はこちらの「Observer.cs」です。
http://xin9le.net/articles/46
よろしくお願いいたします。
Re: このコードの意味を教えてください。
Posted: 2014年3月25日(火) 00:12
by softya(ソフト屋)
<T>はC#のジェネリックスだと思いますがC#にそこまで詳しくないので解説できません。
Observer<T> : IObserver<T>の関係はクラスの継承です。
クラスの継承がわからない段階でジェネリックスに手を出すのは時期尚早だと思いますが、そういう意味の質問でしょうか?
Re: このコードの意味を教えてください。
Posted: 2014年3月25日(火) 08:55
by milfeulle
それはデリゲートのオーバーロードがされているためです。Actionが何なのか気になりますよね? そういう場合はC# Actionなどで検索することでmsdnなどのリファレンスが出てきます。
http://msdn.microsoft.com/en-us/library ... 10%29.aspx
このようにActionデリゲートは、引数なしのデリゲートAction、引数1つのAction<T>、2つのAction<T1, T2>……と16個まで定義されています。(可変長デリゲートがないためでしょう。C++の可変長引数テンプレートみたいにあれば便利ですけどね!)
蛇足ながらデリゲートのオーバーロードの例を提示させて頂きます。もし興味がありましたら、「C# によるプログラミング入門」などで再確認されるとよいと思います。
コード:
using System;
class Program {
delegate void MyDelegate();
delegate void MyDelegate<T>(T t);
public static void Main() {
MyDelegate my_delegate = func;
MyDelegate<int> my_delegate_int = func_int;
my_delegate();
my_delegate_int(100);
Console.ReadLine();
}
public static void func() {
Console.WriteLine("In func()");
}
public static void func_int(int x) {
Console.WriteLine("In func_int({0})", x);
}
}
Re: このコードの意味を教えてください。
Posted: 2014年3月25日(火) 22:21
by シャープ()
ご教授ありがとうございます。
>>softyaさん
私は、「IObserver<T>」の性質を持つ「Observer<T>」というクラスを定義しているのかと思いましたが、これは違うということでしょうか。
クラスの継承については、概念だけはそれとなく頭にあるのですがはっきりと理解できているわけではないのでもう一度調査いたします。申しわけございません。
>>milfeulleさん
リファレンスを確認いたしました。ご提示ありがとうございます。
デリゲートの使い方についても大変わかりやすい例を示していただきまことにありがとうございました。
お恥ずかしながら、今までオーバーロードというのは、もともとある演算子を自分なりに定義しなおすことと思っていました。
「同じ名前のメソッドやコンストラクタを同一クラス内で定義すること」なのですね。
例をご提示いただいたおかげで、また一つ誤解を正すことが出来ました。誠にありがとうございました。
PS:私もやよい好きです。
--------------------------------------------------------
クラスの表記について、今一度調査をいたします。
Re: このコードの意味を教えてください。
Posted: 2014年3月25日(火) 23:16
by softya(ソフト屋)
> 私は、「IObserver<T>」の性質を持つ「Observer<T>」というクラスを定義しているのかと思いましたが、これは違うということでしょうか。
「の性質を持つ」が継承の説明には聞こえるのですが、正確な用語と機能を理解されたほうが良いと思います。
それともどこかの本やサイトに、そう説明されていたのでしょうか?
Re: このコードの意味を教えてください。
Posted: 2014年3月26日(水) 22:18
by シャープ()
>>softyaさん
いいえ、そういった言葉の使い方をしたのは、「継承関係にある」と言ってもその内容の説明にはならないと考えたからです。
「継承」という言葉の意味を文中に使ったほうがよいと考えました。
とはいえ継承をうまく理解できていない可能性のほうが高いので、なるべく早めに再調査いたします。もう少々お待ちくださいませ。
Re: このコードの意味を教えてください。
Posted: 2014年3月26日(水) 23:20
by softya(ソフト屋)
独自の言葉で説明しようとすると大抵は通じないので、共通の言葉を用いて補足的な意味合いで説明しないと訳が分かんなくなるものです。
「ジェネリック クラス (C# プログラミング ガイド)」
http://msdn.microsoft.com/ja-jp/library/sz6zd40f.aspx
ここにあるopen constructed typeのジェネリック クラスの継承だと思いますが。
Re: このコードの意味を教えてください。
Posted: 2014年3月27日(木) 01:51
by milfeulle
継承について迷われているようなので、何かヒントとなれば幸いです :
実は「継承」という言葉には2つの意味がありまして、1つはシャープ()さんの仰るようにオブジェクト指向における概念の一つです。もうひとつはプログラミング言語、今回の場合は特にC#におけるクラスの拡張などを行う言語上の機能のことを指します。
1行目の、classの後は何をしているところですか?
というのは、言語上に於ける継承についてのご質問と言うことでしょうか? そうでしたら入門書を見られるといいと思います。
プログラミング言語C#における継承の最も基本的な例 :
http://ufcpp.net/study/csharp/oo_inherit.html
意味はともかく、プログラミング言語C#における「継承」という機能を使うとどのような動きになるのかご確認下さい。
私は、「IObserver<T>」の性質を持つ「Observer<T>」というクラスを定義しているのかと思いましたが、これは違うということでしょうか。
というと「継承している」といっているのと大して変わらないと思います。実はプログラミング言語C#における「継承」という機能は、3つの場合において使われます。それは、まずは上記のURIのとおりあるクラスの性質を引き継ぐ場合、もうひとつはあるメソッド名を使っていることを明示する場合、最後に抽象的な性質を持つ具体的なクラスを作る場合です。それぞれ、実装継承、インターフェイスの実装、抽象クラスの継承などと呼ばれます。
これらの話は一般的な「オブジェクト指向」でも、「オブジェクト指向プログラミング言語上の機能」でもほぼ同様の概念を持ちますが、まずはプログラミング言語でどのように振る舞うかだけに着目されるといいと思います。
ところで、今回の場合はインターフェイスの継承(実装)です。というのも、C#ではインターフェイスは先頭にIをつける習慣があるためです。入門書を読んで頂くと分かると思いますが、インターフェイスを継承(実装)するというのは、インターフェイスに列挙されているすべてのメソッドとおなじ名前(正確にはシグネチャ)を自分で定義しなければなりません。逆に言うと、(コンパイルが通って)インターフェイスを継承していれば定義されていることが保証されるのです。このありがたさは自分で書いてみないと分からないかもしれません。
その上で、softyaさんお仰るようにジェネリック型でも同様にインターフェイスの実装ができることを確認して下さい。
オフトピック
私の浅い経験と知識に拠りますと、継承を使うのはほとんど2. インターフェイスの実装か3. 抽象クラスの継承になると思います。特に1. 実装継承 ―― もっとも入門書で初めに紹介され、オブジェクト指向言語に初めて触れられる人が理解に努めようとする機能 ―― は、C#(やJava)で嫌われる傾向にあるようです。もし興味がありましたら、この点について「継承 委譲」などで検索してみて下さい。
最後に端的にご質問にお答えしますと、
コード:
class Observer<T> : IObserver<T>
はジェネリッククラスObserver<T>を定義します。ただし、インターフェイスIObserver<T>〔ここでいうTは同一です〕を実装します。言い換えると最低限、インターフェイスIObserver<T>にあるOnCompletedメソッド、OnErrorメソッド、OnNextメソッドをクラスObserver<T>で定義しなければなりません。
コード:
private readonly Action onCompleted = null;
ActionデリゲートonCompletedをprivateで宣言します。onCompletedはActionデリゲートなので、引数を持たず戻り値を返さないメソッドが代入できます。但しこれ以降コンストラクタでしか初期化できません。
PS. 顔文字だけで分かるとはw 同じやよい好き同士がんばっていきましょう!
Re: このコードの意味を教えてください。
Posted: 2014年3月27日(木) 18:12
by ISLe
デザインパターンに見られるようにオブジェクトの性質を引き継ぐ方法は継承に限りません。
なので、性質を持つ=継承、とはならないのです。
解釈とか実装とか関係ないレベルの話です。
できるだけ他人に通じるように言葉を選びましょう、という話ですね。
継承と委譲の両方を知っていたら、ひとくくりに「性質を持つ」で表現しても大して変わらないなんてことは言えないと思います。
自分が知らないことを他人にとっても必要ないことのように置き換えてしまう(勝手な解釈をする)のはとても危険なことです。
オフトピック
実装継承は主にフレームワークレベルでよく使われているように思います。
つまりアプリケーションプログラマには見えないところです。
Re: このコードの意味を教えてください。
Posted: 2014年3月30日(日) 16:33
by シャープ
みなさま、お返事をありがとうございます。
私の無意味な言葉の使い方で混乱を招いてしまい申し訳ございませんでした。
「継承している」と書いただけでは「継承」の意味をわかっているかどうかを疑問に思われるだろうと考えたためこのようなわかりづらい表現となってしまいました。
私は継承について、元のクラスの性質を引き継ぐものだと思っていましたが、それ以外の意味もあるのですね。
実際ほかの意味があるなど理解していなかったため、こちらについてはもう一度確認したいと思います。
milfeulle さんのおっしゃる通り、入門をもっと勉強するべきなのでしょうが現在これらのコードを早急に理解する必要がありどうするべきなのかわかっていないというのが正直なところです。
ご提示いただいたご説明の意味もまだはっきり理解できていないので、一つ一つ調べていきたいと思います。
今回は真にありがとうございました。ご迷惑をおかけして申し訳ございませんでした。
Re: このコードの意味を教えてください。
Posted: 2014年3月30日(日) 18:07
by ISLe
継承によってIObserver<T>の性質を持つクラスObserver<T>を定義している、というふうに書いていたなら問題なかったでしょう。
「継承」と「性質を持つ」の両方を揃えないと、「性質を持つ」が「継承」に関する説明だということが曖昧になります。
意味が分かっているかどうかということではなくて、組み立て方や伝え方の問題です。
いきなり何を言い出すの、と他人に混乱を与えるような行動は、知識だけでは改善しません。
知識だけが先行するとむしろ悪化する場合があります。
プログラミングで言えば設計が上手いか下手かに関わってくる部分だと思います。
Re: このコードの意味を教えてください。
Posted: 2014年3月30日(日) 20:44
by シャープ
>>ISLeさん
解決済みのスレッドであるにも関わらずお返事をありがとうございます。
おっしゃる通りだと思います。そもそも知識自体もないので、なんとか扱えるレベルまで精進したいと思います。
ありがとうございました。