Understanding 'var' Type in C#: Strong or Weak Type?

  • Thread starter Thread starter haki
  • Start date Start date
  • Tags Tags
    Type Weak
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
3 replies · 4K views
haki
Messages
161
Reaction score
0
As far as I understand type systems in strongly typed system such as the one found in Java you must specify the exact type of the variable. Like e.g.

int x = 5; // strongly typed

also this would fail

Object x = 5;
Object y = "Not soo strong are we?";
Object z = x + y; // would throw a compiler error, since + operation is not defined on Object + Object, it is only defined on either Number + Number or String + String or String + Object

Now I said to a friend that C# is no longer strongly typed since in 3.0 you have the var variable which is more of a placeholder than a type, what kind of type is var? var can substitue any type therefore I would say that is weak type. He didn't agree on that one. I am left a bit puzzled. Is var type weak or not? I would say it is.
 
Physics news on Phys.org
It's still strongly typed because the compiler infers the actual type at compile time. In no case would it need a runtime check; I think in ambiguous cases the type must be supplied. It's just a matter of convenience I guess, but I don't understand why it is seen as a good thing. To me it seems that it would make code more difficult to understand.
 
Thanks for the answer. Yeah, I wouldn't dream of using var exept if I would write JavaScript.
 
var is a feature that would be very useful for template programming in C++.

Type expressions can get quite verbose; here's a simple one:

Code:
// Print everything in a container
template <typename Container>
void print_all(const Container &c) {
  typename Container::const_iterator iter = c.begin();
  while(iter != c.end()) {
    std::cout << (*iter++) << std::endl;
  }
}

Sometimes, you have to write stuff like typename Container::const_iterator a lot; it would be very convenient to be able to just write:

var iter = c.begin()


Even worse, sometimes you aren't even supposed to know the return type of an expression. For example, in linear algebra packages, if I write an expression like:

Code:
template <typename T>
void do_something(boost::numeric::ublas::vector<T> &a,
         const boost::numeric::ublas::vector<T> &b,
         const boost::numeric::ublas::vector<T> &c)
{
  a = 3 * b + 4 * c;
}

ublas generates efficient code for this function through the magic of expression templates: each of those arithmetic operations constructs a type that "knows" the parse tree of the expression. For example, the return type of 3*b is


typename vector_binary_scalar1_traits<int, vector<T>, scalar_multiplies<int, typename vector<T>::value_type> >::result_type


which is not only something you wouldn't want to have to type, it's something that you really ought not to even know about! If I wanted to do something like

Code:
var e1 = 3 * b;
var e2 = 4 * c;
a = e1 + e2;

then a keyword like var is the only reasonable option for doing so.