C# doesn't require you to specify a generic type parameter if the compiler can infer it, for instance:
List<int> myInts = new List<int> {0,1,1,
2,3,5,8,13,21,34,55,89,144,233,377,
610,987,1597,2584,4181,6765};
//this statement is clunky
List<string> myStrings = myInts.
Select<int,string>( i => i.ToString() ).
ToList<string>();
//the type is inferred from the lambda expression
//the compiler knows that it's taking an int and
//returning a string
List<string> myStrings = myInts.
Select( i => i.ToString() ).
ToList();
This is needed for anonymous types where you don't know what the type parameter would be (in intellisense it shows up as 'a
) because it's added by the compiler.
Class-level type parameters don't let you do this:
//sample generic class
public class GenericDemo<T>
{
public GenericDemo ( T value )
{
GenericTypedProperty = value;
}
public T GenericTypedProperty {get; set;}
}
//why can't I do:
int anIntValue = 4181;
var item = new GenericDemo( anIntValue ); //type inference fails
//however I can create a wrapper like this:
public static GenericDemo<T> Create<T> ( T value )
{
return new GenericDemo<T> ( value );
}
//then this works - type inference on the method compiles
var item = Create( anIntValue );
Why doesn't C# support this class level generic type inference?
There is no string type in C . You have to use char arrays. By the way your code will not work ,because the size of the array should allow for the whole array to fit in plus one additional zero terminating character.
As such, C programming does not provide direct support for error handling but being a system programming language, it provides you access at lower level in the form of return values. Most of the C or even Unix function calls return -1 or NULL in case of any error and set an error code errno.
The C programming language doesn't seem to have an expiration date. It's closeness to the hardware, great portability and deterministic usage of resources makes it ideal for low level development for such things as operating system kernels and embedded software.
This is due to the fact that C++ does not do bounds checking. Languages like Java and python have bounds checking so if you try to access an out of bounds element, they throw an error. C++ design principle was that it shouldn't be slower than the equivalent C code, and C doesn't do array bounds checking.
Why doesn't C# support this class level generic type inference?
Because they're generally ambiguous. By contrast, type inference is trivial for function calls (if all types appear in arguments). But in the case of constructor calls (glorified functions, for the sake of discussion), the compiler has to resolve multiple levels at the same time. One level is the class level and the other is the constructor arguments level. I believe solving this is algorithmically non-trivial. Intuitively, I'd say it's even NP-complete.
To illustrate an extreme case where resolution is impossible, imagine the following class and tell me what the compiler should do:
class Foo<T> {
public Foo<U>(U x) { }
}
var x = new Foo(1);
Thanks Konrad, that's a good response (+1), but just to expand on it.
Let's pretend that C# has an explicit constructor function:
//your example
var x = new Foo( 1 );
//becomes
var x = Foo.ctor( 1 );
//your problem is valid because this would be
var x = Foo<T>.ctor<int>( 1 );
//and T can't be inferred
You're quite right that the first constructor can't be inferred.
Now let's go back to the class
class Foo<T>
{
//<T> can't mean anything else in this context
public Foo(T x) { }
}
//this would now throw an exception unless the
//typeparam matches the parameter
var x = Foo<int>.ctor( 1 );
//so why wouldn't this work?
var x = Foo.ctor( 1 );
Of course, if I add your constructor back in (with its alternate type) we have an ambiguous call - exactly as if a normal method overload couldn't be resolved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With