I know that Java\'s type system is unsound (it fails to type check constructs that are semantically legal) and undecidable (it fails to type check some construct).
For i
It's not particularly hard to create problems that the C# complier cannot solve in a reasonable amount of time. Some of the problems it is posed with (often related to generics/type inference) are NP-hard problems. Eric Lippert describes one such example here:
class MainClass
{
class T{}
class F{}
delegate void DT(T t);
delegate void DF(F f);
static void M(DT dt)
{
System.Console.WriteLine("true");
dt(new T());
}
static void M(DF df)
{
System.Console.WriteLine("false");
df(new F());
}
static T Or(T a1, T a2, T a3){return new T();}
static T Or(T a1, T a2, F a3){return new T();}
static T Or(T a1, F a2, T a3){return new T();}
static T Or(T a1, F a2, F a3){return new T();}
static T Or(F a1, T a2, T a3){return new T();}
static T Or(F a1, T a2, F a3){return new T();}
static T Or(F a1, F a2, T a3){return new T();}
static F Or(F a1, F a2, F a3){return new F();}
static T And(T a1, T a2){return new T();}
static F And(T a1, F a2){return new F();}
static F And(F a1, T a2){return new F();}
static F And(F a1, F a2){return new F();}
static F Not(T a){return new F();}
static T Not(F a){return new T();}
static void MustBeT(T t){}
static void Main()
{
// Introduce enough variables and then encode any Boolean predicate:
// eg, here we encode (!x3) & ((!x1) & ((x1 | x2 | x1) & (x2 | x3 | x2)))
M(x1=>M(x2=>M(x3=>MustBeT(
And(
Not(x3),
And(
Not(x1),
And(
Or(x1, x2, x1),
Or(x2, x3, x2))))))));
}
}