プロが教える店舗&オフィスのセキュリティ対策術

public SysInfoPanel()
{
Text = "System Information: Panel";
BackColor = SystemColors.Window;
ForeColor = SystemColors.WindowText;
AutoScroll = true;

Graphics grfx = CreateGraphics();
SizeF sizef = grfx.MeasureString(" ", Font);
cxCol = sizef.Width + SysInfoStrings.MaxLabelWidth(grfx, Font);
cySpace = Font.Height;

// Create a panel.

Panel panel = new Panel();
panel.Parent = this;
panel.Paint += new PaintEventHandler(PanelOnPaint);
panel.Location = Point.Empty;
panel.Size = new Size(
(int) Math.Ceiling(cxCol +
SysInfoStrings.MaxValueWidth(grfx, Font)),
(int) Math.Ceiling(cySpace * SysInfoStrings.Count)); //←この部分がエラー
grfx.Dispose();
}

エラー1次のメソッドまたはプロパティ間で呼び出しが不適切です: 'System.Math.Ceiling(decimal)' と 'System.Math.Ceiling(double)'

↑こういうエラーが出てコンパイルできません。visualstudioの2005から2013まで試しましたがだめでした。
書籍付属のコンパイル済みのexeファイルは正常に動くので何が間違っているやら

A 回答 (5件)

元問題は解決しているようですのでANo.2補足への回答です。


オーバーロードは、同名の関数から引数の型によりコンパイラが正しい関数を選択する機能です。
引数と完全に一致する型の関数がない場合は暗黙の型変換が行われますが、それによって選べる関数が複数になると、正しい関数を特定できないためコンパイラがエラーを出します。今回の質問の問題はこのケースです。
ポリモフィズムは実行時のオブジェクトの型によって実行する関数が変わる機能です。実行時のオブジェクトの型が特定できないということはないので実行時エラーはないですね。多重継承で実行できる関数が複数になる場合はコンパイルエラーでしょう。
    • good
    • 0
この回答へのお礼

オーバーロードとポリモーフィズムの違いがわかりました。
すっきりしました。またよろしくお願いします。

お礼日時:2014/01/21 12:13

ちなみに……


> doubleかdecimalかどっちかにする、
> オーバーロードという機能はそのどっちかを自動で推論してくれる機能?だと思ったのですが
> 明示的にしないとだめなのですね。
オーバーロードは「多重定義」のことです。
コンパイラは引数に応じて、複数あるオーバーロードのうちのどれを使うかを判断しますが、
候補を1つに絞りきれないと今回のようなエラーになります。
    • good
    • 0

> cxColはfloat型 SysInfoStrings.MaxValueWidth(grfx,Font));もfloat型を返します。


> decimalでもdoubleでもないのにエラーが出なかったのはなぜでしょう
型変換には「明示的な型変換(キャスト)」と「暗黙の型変換」とがあります。

intの場合、暗黙の型変換でdoubleにもdecimalにも直せます。
・int → double
 int i = 10;
 double d = i; //暗黙の型変換が可能なのでエラーにならない
・int → decimal
 int i = 10;
 decimal d = i; //暗黙の型変換が可能なのでエラーにならない

一方、floatは暗黙の型変換ではdoubleにしか直せません。
・float → double
 float f = 10f;
 double d = f; //暗黙の型変換が可能なのでエラーにならない
・float → decimal
 float f = 10f;
 decimal d = f; //暗黙の型変換はできないのでエラーになる
 d = (decimal)f; //キャストすれば変換可能

そのため、コンパイラは「どっちを呼べばいいの?」と迷う必要はなくなります。
(この場合はMath.Ceiling(double)が呼ばれます)

参考URL:http://msdn.microsoft.com/ja-jp/library/y5b434w4 …
    • good
    • 0
この回答へのお礼

ありがとうございます すっきり納得しました。
decimalというのが初耳でした。もっと勉強いたします。

お礼日時:2014/01/21 12:11

#1の通りなら、整数*整数は整数なので、Ceiling 自体不要なわけで。


元のサンプルは cySpace か SysInfoStrings.Count が、double型等になっていませんか?

この回答への補足

はい 両方int型です。 どうもそれがいけないみたいでdouble型にキャストしたらコンパイルできました。
オーバーロードというのは引数に応じて処理を推論してくれる機能ですよね?
多態性ポリモーフィズムと勘違いしてますか?

補足日時:2014/01/21 09:01
    • good
    • 0

エラーの内容がよく分からない時は、エラーメッセージでGoogle検索等してみましょう。


(まぁこのエラーメッセージじゃ何のことかわかりにくいですよね……)


まず、Math.Ceilingメソッドですが、MSDNを見ると、
 Math.Ceiling(decimal)
 Math.Ceiling(double)
の2つのオーバーロードがあることが分かります。
http://msdn.microsoft.com/ja-jp/library/system.m …

cySpaceの型に関する記載がありませんが、int型の変数ですか?
cySpaceがint型とすると、
 cySpace * SysInfoStrings.Count
の計算結果はint型になります。

しかし、int型の引数が使えるMath.Ceilingメソッドのオーバーロードはありません。
(int型の値にMath.Ceilingを使う意味はないので当然ですが)

なので、decimalかdoubleにキャストする必要があるわけですが、
int型はキャスト演算子なしでdecimalにもdoubleにも変換することができます。
そのため、コンパイラからすると、
 「Math.Ceiling(decimal)とMath.Ceiling(double)のどっちを呼べばいいの?」
ということになります。

ということで、
 Math.Ceiling((decimal)cySpace * SysInfoStrings.Count)
または、
 Math.Ceiling((double)cySpace * SysInfoStrings.Count)
と書いて、どっちのMath.Ceilingを呼ぶかを指示してあげてください。

この回答への補足

ありがとうございます。キャストをしたらできました
Math.Ceiling()を使わないでコンパイルしてもできました。

intなのでMaty.Ceiling()を使う必要がない、doubleかdecimalかどっちかにする、
オーバーロードという機能はそのどっちかを自動で推論してくれる機能?だと思ったのですが
明示的にしないとだめなのですね。

一つちょっとした疑問が残るのですが、エラーとなっていた行の一つ上、
(int)Math.Ceiling(cxCol + SysInfoStrings.MaxValueWidth(grfx,Font));

の部分なのですが、cxColはfloat型 SysInfoStrings.MaxValueWidth(grfx,Font));もfloat型を返します。

decimalでもdoubleでもないのにエラーが出なかったのはなぜでしょう

補足日時:2014/01/21 08:58
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!