「型安全」とはどういう意味ですか?
ベストアンサー1
型の安全性とは、コンパイラがコンパイル中に型を検証し、変数に間違った型を割り当てようとするとエラーをスローすることを意味します。
簡単な例をいくつか挙げます。
// Fails, Trying to put an integer in a string
String one = 1;
// Also fails.
int foo = "bar";
これは、明示的な型を渡すメソッド引数にも適用されます。
int AddTwoNumbers(int a, int b)
{
return a + b;
}
次のように呼び出そうとすると:
int Sum = AddTwoNumbers(5, "5");
文字列 ("5") を渡しているのに整数を期待しているため、コンパイラはエラーをスローします。
JavaScript などの緩く型付けされた言語では、次のことができます。
function AddTwoNumbers(a, b)
{
return a + b;
}
次のように呼び出すとします:
Sum = AddTwoNumbers(5, "5");
Javascript は自動的に 5 を文字列に変換し、「55」を返します。これは、Javascript が文字列の連結に + 記号を使用するためです。型を認識するには、次のようにする必要があります。
function AddTwoNumbers(a, b)
{
return Number(a) + Number(b);
}
あるいは、次の可能性もあります:
function AddOnlyTwoNumbers(a, b)
{
if (isNaN(a) || isNaN(b))
return false;
return Number(a) + Number(b);
}
次のように呼び出すとします:
Sum = AddTwoNumbers(5, " dogs");
Javascript は自動的に 5 を文字列に変換し、追加して「5 匹の犬」を返します。
すべての動的言語が JavaScript のように寛容なわけではありません (実際、動的言語は暗黙的に緩い型付けの言語を意味するわけではありません (Python を参照))。一部の動的言語では、無効な型キャストに対してランタイム エラーが発生します。
便利ではありますが、簡単に見逃されてしまうエラーが多数発生し、実行中のプログラムをテストすることによってのみ特定される可能性があります。個人的には、そのような間違いがあった場合にコンパイラが教えてくれる方が好みです。
さて、C# に戻りましょう...
C#は、と呼ばれる言語機能をサポートしています。共分散これは基本的に、基本型を子型に置き換えてもエラーが発生しないことを意味します。次に例を示します。
public class Foo : Bar
{
}
ここでは、Bar のサブクラスとなる新しいクラス (Foo) を作成しました。これでメソッドを作成できます。
void DoSomething(Bar myBar)
Foo または Bar のいずれかを引数として使用して呼び出すと、どちらもエラーを発生せずに機能します。これが機能するのは、C# が Bar の子クラスが Bar のインターフェイスを実装することを認識しているためです。
ただし、逆はできません。
void DoSomething(Foo myFoo)
この状況では、Bar が Foo のインターフェースを実装していることをコンパイラが認識しないため、このメソッドに Bar を渡すことはできません。これは、子クラスが親クラスと大きく異なる可能性がある (通常は異なる) ためです。
もちろん、今では私はかなり脱線し、元の質問の範囲を超えていますが、すべて知っておくべき良いことです :)