<blockquote>
  <p>Then I inevitably have students who abandon the good habits they had formed and want to make everything an Object</p>
</blockquote>

<p>This can easily be shown to be a bad approach if you need a class specific property later on.</p>

<pre><code>object myStudent = new Student("John", "Doe");

string name = myStudent.Name; //doesn't work
</code></pre>

<p>They'll probably use a hard cast, at which point the issue is no longer that they use object, but that they are losing out on type safety.</p>

<p>The problem here is that an adequately skilled student who is ahead of the curve will always be able to work around simple pitfalls. If he is overskilled for the example, he has more than enough brainpower to ensure that his hard casts always work.<br>
The only way to force them to make mistakes is to give them a sufficiently complex example, where they're struggling with the core intention so much that having to manage hard casts on top of that just makes everything so much worse.</p>

<p>But you may have to single them out for this complex task; which can in and of itself signal that they don't <em>need</em> to complete this hard task (since you can't just make tests harder for a particular student).</p>

<p>The only guaranteed solution is to explicitly disallow hard casting in the problem statement.<br>
Any other (more implicit) approach is liable to be a cause for complaints when the student loses grades over this.</p>

<blockquote>
  <p>I am always torn about how insistent to be that they revert, because I know the use of var in C# is controversial in the industry. (See the SO discussion use of var in C# for an example). </p>
</blockquote>

<p>Your conclusion does not match your observation. Suppose the community is split 50/50 between either using <code>var</code> freely, or not using it at all. That means that <strong>either choice is equally correct</strong>.<br>
Standards and conventions are, unsurprisingly, decided by convention.</p>

<p>The only things you should be telling your students to not do are the things that a majority of the community agrees are bad approaches (such as hard casting for no good reason).</p>

<hr>

<p>This goes even further. <code>var</code> may actually be the solution to your <code>object</code>-focused students. In all likelihood, they are choosing the blanket use of <code>object</code> because they find it unnecessarily hard to always write the correct type. <strong><code>var</code></strong> solves that problem by having the compiler (not the developer) figure out the types that are trivial to look up. </p>

<p>You're seeing this as two similar issues, but it's much more likely that one (<code>object</code>) is a consequence of your reluctance to allow the other (<code>var</code>).</p>

<hr>

<blockquote>
  <p>Plus, the more savvy students are hanging out in SO anyway, and they see some questions and answers that lack explicit typing and other good programming habits.</p>
</blockquote>

<p>This is again a matter of convention. If students are predominantly exposed to "StackOverflow code quality", then it makes sense for them to adapt "StackOverflow code quality". </p>

<p>Being better than your surrounding is not always objectively better. The first company I worked in was comprised of self-taught developers and <em>one</em> university graduate. His solutions were much more theoretical than ours. But he couldn't make those solutions work in our company, because everyone else disagreed with him.  </p>

<p>While I'm not in any way arguing that CS theory is bad; you do need to realize that pretty much every argument of code quality rests on <strong>convention</strong>, not objectively provable superiority. If something were actually illogical or inferior, then no one would keep advocating its use, thus eventually rendering it outdated.</p>

<p>What you're trying to do, with the best of intentions, can also be construed to be bordering on requiring students to adhere to <strong>your</strong> preferred standard as opposed to the average community standard.</p>

<blockquote>
  <p>My question is, since these students are still learning, and since it is my classroom after all, should I emphatically require that they always explicitly specify types unless absolutely necessary? </p>
</blockquote>

<p>As a teacher, it is your prerogative to be selective about what you consider a correct answer. However, if you are requiring a particular standard to be upheld, then you should <strong>explicitly</strong> mention this.</p>

<p>If you ask your students for "an application that does [thing]", then you're implying that any working code is a correct answer to the question (which deserves full marks).<br>
If you ask your student for "an application that does [thing] and avoids string concatenation (<code>+</code>)", then you've made it clear that working code that uses string concatenation is not a correct answer to the question.</p>

<p>If you want to force a particular answer, you must phrase your question accordingly. Do not punish students for an implicit convention, because most students expect questions that reveal how their answer will be graded.</p>

<blockquote>
  <p>And, if I do require it, how can I explain the (in my opinion) sloppiness they sometimes see in online communities?</p>
</blockquote>

<p><em>"Just because it works, does not mean it works well."</em> is what my teacher used to tell me. And I was the kind of student who needed to repeatedly be told that.</p>

<blockquote>
  <p>(Of course, sometimes it is justifiable, preferred, and necessary NOT to). </p>
</blockquote>

<p>Just out of curiosity, when is <code>var</code> ever a necessity? I can't think of a single case. As far as I'm aware, <code>var</code> is merely shorthand, not an actual technical benefit.</p>

CC BY-SA 4.0
2018-05-04T07:37:11.507Z
`var` is absolutely necessary in some contexts with anonymous types, which AIUI was one of the motivations for introducing it. My answer to this question also mentions a situation (`foreach` loops) where getting into the habit of using `var` always will allow the detection of problems at compile-time rather than runtime.
Peter Taylor
CC BY-SA 4.0
2018-05-02T09:44:50.000Z
2018-05-02T09:44:50.000Z
Flater
<p>Various forms of the same question to ask oneself:</p>

<ul>
<li>Does this "thing" represent part of my design?</li>
<li>Is it a key aspect of a contract?</li>
<li>Do I want to <em>anchor</em> my thinking around a specific type at this point in my code?</li>
</ul>

<p>In all cases a strict type declares to my reader (myself in 6 months) that this is important.  If it's less important, let it go.</p>

<hr>

<p><em>an implicit reference to a Disney movie is not explicitly declared, so it's not an anchor point for my argument.</em></p>

CC BY-SA 3.0
2018-04-30T23:57:48.103Z
2018-04-30T23:57:48.103Z
Richard Sitze
<p>Teach them c/c++ first, or go into the common uses of each data type first so they have to understand the intrinsic properties.</p>

CC BY-SA 3.0
2018-04-30T20:02:35.603Z
2018-04-30T20:02:35.603Z
Mike
<p>There are a few reasons why this is bad, for example it could lead to code issues down the line where you need something from <code>Horse</code> that you don't have on <code>Object</code>, and it may also be a code smell. I'm going to suppose the code passes and runs fine, the architecture is fine, and just focus on the remaining issue: the issue generally is of course that it's not as specific as it could be, and the reason that's bad is it's bad for maintainability and code clarity.</p>

<p>In general, for maintainability, you want your code to model your ontology, to be resilient to counterfactuals. That way, if things need to change in the future, your code will more likely be constructed in a way thats amenable, because even though certain specifications changed, or some refactoring is being done, your code is still basically modeling the logic of the situation.</p>

<p>So <code>Object x = new Horse("silver")</code> is bad because <code>x</code> is not just an <code>Object</code>, it's a <code>Horse</code>, maybe it's an <code>Animal</code>.</p>

<p>(1) You lose the code clarity, future readers won't have the info of immediately knowing, if they want to change the value of <code>x</code>, what <code>x</code> "is" and a sense of how it's going to be used.</p>

<p>(2) You lose benefits of type-checking, because anything using <code>x</code> only knows it's an <code>Object</code> and doesn't know it's a <code>Horse</code>.</p>

<p>I'm not a teacher, I'm just a programmer in industry, but I think maybe the single most important general principle I use in my day to day is: code should model ontology, including in the sense that it's robust to counterfactuals. A lot of bad code falls under that category.</p>

CC BY-SA 3.0
2018-04-30T21:00:18.477Z
2018-04-30T21:08:52.240Z
2018-04-30T21:08:52.240Z
anonymous
<blockquote>
  <p>Then I inevitably have students who abandon the good habits they had
  formed and want to make everything an Object, or declare everything as
  var.</p>
</blockquote>

<p>These are very different situations. As you observe, the use of <code>var</code> in C# is controversial, but using <code>object</code> as the type of all variables (and then needing to cast any time you want to actually <em>use</em> the variable) is not controversial: it's just wrong.</p>

<p>The first page of answers on the linked SO question about <code>var</code> in C# is incomplete. It doesn't mention that using <code>var</code> can avoid bugs due to typing in one edge case: <code>foreach (var foo in foos)</code> vs <code>foreach (Foo foo in foos)</code>. For legacy reasons, if <code>foos</code> is a <code>System.Collections.IEnumerable</code> but not a <code>System.Collections.IEnumerable&lt;&gt;</code> the latter is equivalent to <code>foreach (Foo foo in foos.Cast&lt;Foo&gt;())</code>, which is not especially obvious. (In fact I misremembered and was corrected in comments, which reinforces the advantage of using <code>var</code> here).</p>

<p>TL;DR: blanket prohibitions on <code>var</code> are almost certainly going too far.</p>

<blockquote>
  <p>My question is, since these students are still learning, and since it
  is my classroom after all, should I emphatically require that they
  always explicitly specify types unless absolutely necessary? ...
  And, if I do require it, how can I explain the (in my opinion)
  sloppiness they sometimes see in online communities?</p>
</blockquote>

<p><code>var</code> is far from the only controversial subject in programming praxis. The solution in industry is the style guide: whether as a formal written document or as an informal internalised set of opinions which are imparted to new team members by word of mouth when they submit changes which violate the house style. If you're explicitly preparing your students for industry, it is perfectly reasonable to dedicate a bit of time to explaining the concept of the house style, and then when you introduce new material to explain the house style you will enforce for that feature.</p>

<p>The really heavy-duty approach would be to prepare a full industry-style style guide and then to produce a series of increasingly large subsets so that every couple of weeks you can give them a link to an updated style document which specifies how to use the new features you just introduced, or the new features you're about to introduce, and highlights the additions from the previous one.</p>

CC BY-SA 3.0
2018-04-30T14:03:51.830Z
Yes, the overuse of Object/var are different situations, but in my experience the tendency for new(-ish) programmers to resort to their use in laziness is about the same.  I do mention to them that a style guide will probably be present in their careers and that they should plan to conform to it.  Having a written one for my classroom would be good practice for that.  Maybe I'll get them to write it!
Java Jive
CC BY-SA 3.0
2018-04-30T14:13:06.083Z
Often enough the style guide is _not_ about making the program, in its initial state, better, or the programmer's job any easier. It is, however, about making the "clarity" clearer for any programmer who later deals with that code, including the author. Few rules in style guides are based on rules in the language, but rules in the praxis of the author(s) of the guide.
Gypsy Spellweaver
CC BY-SA 3.0
2018-05-01T08:59:31.003Z
`foreach (Foo foo in foos)` is somewhat equivalent to `foreach (Foo foo in foos.Cast<Foo>())`. It will throw `InvalidCastException` not filter by actual type like `OfType<T>`.
Johnbot
CC BY-SA 4.0
2018-05-02T00:38:56.497Z
Why write your own style guide?  Use the one that is official to the language.
pojo-guy
CC BY-SA 4.0
2018-05-02T07:31:11.293Z
@pojo-guy, that's a fair point (when one exists), but it would create copyright problems with the subsetting, and dumping a full style guide which talks about features you won't mention for 3 months is not ideal.
Peter Taylor
CC BY-SA 3.0
2018-04-30T13:57:30.200Z
2018-05-01T09:50:56.227Z
2018-05-01T09:50:56.227Z
Peter Taylor
<p>If I learned anything reading Dale Carnagie, if you want to convince someone to do something, don't tell them "Do this because I want you to," tell them "Do this because if you don't, you're going to suffer for it and it's your loss." Speak in terms of their own self interest. </p>

<p>You might want to tell them, "Now, you may want to use Objects for everything. This is bad and it will suffer because of it. You'll get weird errors when you start using it. If you don't want to spend 30 minutes debugging a program for a silly error, don't use Object like that. Here are some examples of using Objects will make your life more painful..."</p>

<p>As far as using var for everything, I'm a professional programmer and I use var all the time. I can't help you there (if I were one of your students, I would wonder why I couldn't work more efficiently either!). It's important to know what type you're working with, but as long as you do that, <em>var</em> away. </p>

CC BY-SA 3.0
2018-04-30T18:15:55.380Z
I am/was a professional programmer too, and I always use types when I declare.  The only place I think var is justified is when working with LINQ queries and their results (foreach var...).  Efficiency now causes headaches later.
Java Jive
CC BY-SA 3.0
2018-04-30T18:26:58.653Z
@JavaJive That's fine... it's ultimately a matter of debate. But honestly, as a mildly rebellious student myself I would have chafed under required "vars" if there isn't an airtight case for them (which there isn't). Then again, I don't know much about teaching so I can't say when you should lay down the law and when you should back off.
John von No Man
CC BY-SA 3.0
2018-04-30T17:59:31.367Z
2018-04-30T17:59:31.367Z
John von No Man
<p>If you expect that many of the students will pursue software development careers, it would not be unreasonable to declare style standards for the course, and include it in their grading.</p>

<p>When doing so, I strongly recommend explaining <em>why</em> particular rules are in place, because it moves disagreement into "arguing principles" instead of having "arbitrary rules".</p>

<p>The explanation could be as simple as "we're going to follow the <a href="https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md" rel="noreferrer">corefx style guidelines</a>" because the majority of example code produced by the .NET development team will adhere to these rules.</p>

<blockquote>
  <ol start="10">
  <li>We only use <code>var</code> when it's obvious what the variable type is (e.g. <code>var stream = new FileStream(...)</code> not <code>var stream = OpenStandardInput()</code>).</li>
  </ol>
</blockquote>

<p>Or, the rules could be a bit more esoteric/practical. As a grader many years ago I got the professor to agree to a style score as a portion of the coursework. I told the class "I will be reviewing your code with the program <code>less</code> in an 80-character wide terminal.  If I have to horizontally scroll you will get 0 points for style." -- I think I gave a 0 for breaking that rule just once.</p>

CC BY-SA 3.0
2018-04-30T23:02:01.797Z
2018-04-30T23:02:01.797Z
bartonjs
<p>There are a number of issues to be addressed from clarity of the written code to efficiency of the compiled code. For beginners, I think the clarity issue is more important so I'll address that first. </p>

<p>Before I begin, though, I'll also note that the inferred typing of variables in C# is still static (compile time), strong (types don't change) typing. That hasn't changed. Inferred typing is just a syntactic hack (syntactic sugar) that appear to make the programmer's job easier. However, that is only true when you are writing the program the first time, not when you are updating/modifying/maintaining the program. </p>

<p>I'll note also, that programming languages are for people, not for computers. Compilers take the human-understandable code that we write and transform it into something that a machine can utilize. </p>

<p>Specifying the type of a variable in a declaration, while not always required introduces a kind of <em>good</em> redundancy. Much redundancy in programming is bad (repeating a sequence of statements) but redundancy in typing is good since it makes the <em>intent</em> of the programmer clearer and also, in some situations finds errors in a program at compile time that could otherwise only become noticeable at run-time. This lets the programmer fix issues earlier in the development process, which, research shows, reduces cost. </p>

<p>Think of the phases of program development as follows: conceptualization, analysis, design, coding, testing, deployment, maintenance (maybe not a universally agreed list, I realize). Research shows an order of magnitude increase in the cost of correction for each phase transition. If you catch the error in the conceptualization phase it costs nearly nothing to fix. (Sorry, I don't have a reference to the research - it is quite old). </p>

<p>When you say that a variable is int and later (or immediately) assign it an int value the compiler can check correctness. But you the program reader are also assured that your intent (x is an int) is faithfully represented in the code. </p>

<pre><code>var x = 5;
</code></pre>

<p>reduces the redundancy. Note also that 5 is a valid value of the following C# types: byte, sbyte, int, uint, long, ulong, short, and ushort. What is your intention here. The declaration above doesn't say. The compiler will choose something it "thinks" is appropriate. By saying less about your <em>intent</em> you give less information to the compiler, which may then provide a less-than-optimal translation of your code. So this sort of redundancy is a good thing. </p>

<p>When used with objects (or otherwise polymorphic types) there is an additional consideration. </p>

<p>If you say</p>

<pre><code>var x = new Horse("Trigger");
</code></pre>

<p>then the compiler has little recourse than to give x the most specific possible type. It might, in fact be preferable to give x a more general type, such as an interface type used to create the Horse class. It is generally good programming practice to give variables interface (as opposed to class) types, though this requires other rules about how interfaces are used - a separate discussion. But, in some contexts</p>

<pre><code>Animal x = new Horse("Trigger");
</code></pre>

<p>might be preferable and it also better clarifies your <em>intent</em>.</p>

<p>None of the above uses of <em>var</em> is necessarily a mind-killer, but an alternative use of what I want to call <em>sloppy typing</em> is. </p>

<p>Suppose you declare a new object reference as follows:</p>

<pre><code>Object x = new Horse("Trigger");
</code></pre>

<p>Now you have likely introduced a mess into your program. Later on, you will probably want to say</p>

<pre><code>int howMany = x.count();
</code></pre>

<p>(We know, horses like Trigger can count, of course). The compiler will complain about this, of course since x is only known as an Object reference, not a Horse reference. The sloppy typer will then <em>cast</em> x to quiet the complaints of the compiler:</p>

<pre><code>int howMany = ((Horse)x).count();
</code></pre>

<p>which is, of course ugly. We need to assure the compiler that x is, indeed, a Horse so that the <em>count</em> method is available. However, this cast introduces a check into the runtime code, which is both inefficient <em>and</em> can be wrong. What if somewhere else prior to this x was reassigned to an Aardvark object. Then whether or not Aardvarks can count or not, the run-time type check will flag an error. </p>

<p>This sloppy typing combined with casting is an attempt to replace the normal static type checking with dynamic type checking (as is done in, say Python). But that is misuse of the language. </p>

<p>Moreover, it introduces a maintenance nightmare into your program. You declare a variable in your program to have a given type, but in use it has a different (more specific) type. The compiler isn't going to remember those actual types for you, so you have to do this yourself. You can't look back to the declaration of x to find out what sort of thing it represents, you have to keep the details of the dynamic system in mind for every use of the variable. In a program of any size this is obviously infeasible. It is why we have types (and also polymorphism) in the first place. </p>

<p>Again, this sort of casting (down casting) is a recognized <a href="https://en.wikipedia.org/wiki/Code_smell" rel="nofollow noreferrer"><em>Code Smell</em></a>, indicating poor design. Every explicit cast in a program is a potential point of error. Just Say No. </p>

<p>For completeness, let me give a few rules here that will lead to better design and better code. </p>

<ol>
<li><p>When you declare a variable give it an interface type (rather than a class type) - a good but not essential rule. Interfaces define <em>concepts</em>. </p></li>
<li><p>When you implement that interface the only public methods of the class should be those defined in the interface. You won't need to cast. - an essential rule.</p></li>
<li><p>When you extend a class (create a subclass) the only public methods in the subclass should be those declared in the superclass. Essential. If you need more methods then you have a different concept than the superclass, so extend the interface of the original class to define the new concept and then have the subclass also implement the new interface. </p></li>
<li><p>When you declare a variable to have some (object) type, don't try to send messages defined only in some subtype, requiring casting. </p></li>
</ol>

<p>The above rules are intended to make your programs easier to understand, hence easier to update and maintain. When tempted to break the rules, spend a bit of time asking why, and looking to see if you can come up with a better design. Breaking the rules tends to make your overall program into a <a href="https://en.wikipedia.org/wiki/Big_ball_of_mud" rel="nofollow noreferrer">Big Ball of Mud</a>.</p>

<p>All of the above has focused, primarily, on clarity of the code for the programmer's benefit. But efficiency is also a consideration. </p>

<p>The more you can inform the compiler of your intent, the better job it can do in its translation. Some languages optimize for expressing intent rather than process, in fact. Database languages and Logic languages do this explicitly. If you tell a compiler <em>how</em> to do something it will be constrained to follow your directions. But if you tell it what you want, rather than how to achieve it, it has more options and can do better optimizations. So, explicit typing in programs is also a way to communicate intent (what) to the compiler rather than forcing later checks (casts). So, maybe x in our first example really only needs to be a short, or even a byte. But the declaration using <em>var</em> probably won't achieve that. </p>

<p>I also realize that "abstract" names like <code>x</code> are a poor choice. I only use it here as I don't have a context in which to provide an <em>intention revealing name</em>. </p>

<hr>

<p>History note:
Implicit typing is probably an incorrect term for this. FORTRAN had implicit typing where the type of a variable depends on the spelling of the name. Names beginning with I through N were implicitly Integer unless a specific declaration implied otherwise. Other names indicated Real variables. </p>

<p>On the other hand, Standard ML and related languages have a subsystem in the compiler that could infer types (type inference). ML has strong static typing also, but programmers seldom need to specify a type since the compiler can ordinarily figure it out. </p>

<p>But use of <em>var</em> isn't dynamic typing either. In dynamic typing (Python, Ruby), variables (names) don't have type. Only values have type. Dynamic typing can still be strong typing, but it is done at run-time, not compile-time. Errors are found later unless they are rigorously rooted out through testing during development. </p>

<hr>

<p>Final Note:</p>

<p>The biological classification of Carl Linnaeus is probably a poor analogy to use for subclassing and polymorphism. Each entry in the classification tree is a different concept and all are abstract. There is no such thing as a pure Mammal. Moreover, classes define behavior of objects (via public methods) and the Linnaeus classification system is <em>nothing</em> about behavior. Trying to use it to generate examples of subclassing is one of the reasons students get terrible ideas about what <em>should</em> be done in a subclass. </p>

CC BY-SA 3.0
2018-05-01T16:53:43.643Z
Variables can be used either to represent values or containers.  One could use a value of type `Horse` which identifies a `Horse` just about anyplace one could value of type `Animal` that identifies a `Horse`, but a *container* of type `Horse` which will always a `Horse` any time it's not null is very different from a container of type `Animal` which *initially* identifies a `Horse`, but might later identify a `Dog`.
supercat
CC BY-SA 3.0
2018-05-01T17:26:19.403Z
@supercat, sorry, not sure how you are using the term _container_ here. Are you contrasting reference (i.e. heap) values from others?
Buffy
CC BY-SA 3.0
2018-05-01T18:21:47.070Z
If I say `int x=someComputation();` and never write to `x`, then within its scope `x` would be synonymous with the value yielded by that call to `someComputation`.  If instead I say, `int x=0;` and later within a loop say `x+=someOtherComputation;`, then there would be no particular value with which `x` would be associated throughout its scope.  Instead `x` would be used as a place to store computations which are performed throughout its lifetime.
supercat
CC BY-SA 3.0
2018-05-01T19:52:42.773Z
@supercat, If you have some way to specify that x is a constant (const in C++, final in Java, etc) then yes. Otherwise the system will treat both the same and it is only your intention that makes them different.
Buffy
CC BY-SA 3.0
2018-05-01T20:11:37.120Z
The system will treat both the same, true.  On the other hand, programs are usually intended to be read not just by computers but also by people.
supercat
CC BY-SA 3.0
2018-05-01T20:14:43.553Z
@supercat, that isn't the point. If the restriction can't be communicated nor enforced it doesn't _really_ exist. The next person to read the program won't understand it or be bound by your intention during maintenance. The code itself should express your intention. Comments can help a bit, but they have to be read and agreed to. Make the code express the intention.
Buffy
CC BY-SA 3.0
2018-04-30T13:26:32.267Z
2018-04-30T13:55:18.857Z
2018-04-30T13:55:18.857Z
Buffy
<p>Introducing these sorts of shortcuts can cause exactly the problem that you've outlined.  <em>"Oh, goody!"</em> says the misguided student, <em>"Now I can stop worrying about the type!"</em></p>

<p>There are a few principles that I directly teach, and repeat extensively in my instruction:</p>

<ol>
<li>There are two audiences for code, machines and people.  We need to create code that is good for both.</li>
<li>Compiler errors are better than runtime errors.  (This is hard for kids to understand at first, but I return to this idea repeatedly until it is thoroughly drilled into their heads.)</li>
<li>All code must be written with the Four <code>C</code>'s in mind: <code>Clarity</code>, <code>Clarity</code>, <code>Clarity</code>, and <code>Clarity</code>.</li>
</ol>

<p>It has never particularly occurred to me to illustrate that every variable could be declared an Object instead of with a more specific subtype, but the following terrible code could illustrate the dangers of doing this.  (This is in Java, but could just as readily be created in C#):</p>

<pre class="lang-c prettyprint-override"><code>/* Pre-condition: Object[] passed in is length &gt;= 1
 * arrange puts an Object into o[0];
 */
public void arrange(Object[] o){
    int rand = (int) (Math.random()*4);
    if (rand == 0)
        o[0] = "This is a String!";
    else if (rand == 1)
        o[0] = new Integer(37);
    else if (rand == 2)
        o[0] = new Double(3.1415926);
    else {
        o[0] = new Object[1];
        arrange((Object[]) o[0]);
    }
}
</code></pre>

<p>Of course, code like this should make us want to puke just a little bit into our mouths.  <em>We'd ideally want the compiler to stop us.</em>  and that's the key point: declaring variables as <code>Object</code> removes our beautiful compile-time protections, and leaves both the coder and other human readers adrift.  Sure, it's an <code>Object</code>, but what in the world <em>is</em> it?</p>

<p>Similarly, with <code>var</code>, you can borrow some examples from the very page you linked to illustrate why <code>var</code> can be a bad idea.  I also might not introduce the concept until you have introduced Generics, as that is one of the first times that it can actually make things easier.  This would allow you to couple the example of where it can make things easier with examples of where it also can make things insanely more difficult (the more over-the-top, the better for your illustrating purposes).  This will enable you to have a discussion about appropriate usage based on real principles, not just course policy.  </p>

<p>After this discussion, you can explain where you will accept these in your course, and there should be little resistance from your students.  After all, what you are asking for is simply <em>sensible</em>.  Hopefully, this will allow you to create some balance in the lab work you receive.</p>

CC BY-SA 3.0
2018-04-30T17:27:45.653Z
I remember when C♯ and Java were like this. Containers were containers of Objects (except arrays).
ctrl-alt-delor
CC BY-SA 3.0
2018-05-01T16:46:51.780Z
I think point #2 is one of the most important, and it's one that I wish language designers would pay more attention to.  If there are two things a piece of code might plausibly be intended to mean, and if a slight adjustment would make the intent unambiguous, having a language require that a programmer be explicit in both cases may be better than having it allow one to be implicitly assumed.  From a teaching perspective, though, I think the issue is probably that if one fixes all the underlying problems that could lead to compile errors, one may be close to having a working program, and...
supercat
CC BY-SA 3.0
2018-05-01T16:50:30.227Z
...this in turn wants causes students to want to reach the point of having their program compile successfully as soon as possible.  What's important for them to learn is that there are ways of making programs compile successfully without fixing their real problems, but if one uses such approaches the real problems will still remain.
supercat
CC BY-SA 4.0
2018-05-02T14:59:37.213Z
@ctrl-alt-delor I remember when golang was like that... oh, wait...
Jared Smith
CC BY-SA 4.0
2018-04-30T13:47:47.687Z
2018-08-30T17:55:40.953Z
2018-08-30T17:55:40.953Z
Ben I.
<p>I typically have the same students two semesters in a row, for programming I (VB.NET) and programming II (C#). In our early, impressionable time together, I stress to these students (high-schoolers) and show them by example (I write lots of code for them) the importance of writing clear, readable code, which is partly achieved by explicitly specifying types for all variables (at first I do not tell them there are other options)</p>

<p>However, at some point, I have to reveal to my students that they can, indeed, declare a variable as an <strong>Object</strong> (i.e. <code>Object x = new Horse("Silver");</code>) and that it can hold anything; or, that they can declare a variable as <strong>var</strong> (i.e. <code>var y = "foo";</code>) and that the compiler will figure out what type it is. Some of them discover this on their own, of course.</p>

<p>Then I inevitably have students who abandon the good habits they had formed and want to make everything an Object, or declare everything as var (note I realize this is not equivalent in the language, but students tend to abuse the usage in the same way). I am always torn about how insistent to be that they revert, because I know the use of var in C# is controversial in the industry. (See the SO discussion <a href="https://stackoverflow.com/questions/41479/use-of-var-keyword-in-c-sharp">use of var in C#</a> for an example). Plus, the more savvy students are hanging out in SO anyway, and they see some questions and answers that lack explicit typing and other good programming habits.</p>

<p>My question is, since these students are still learning, and since it is my classroom after all, should I emphatically require that they always explicitly specify types unless absolutely necessary? (Of course, sometimes it is justifiable, preferred, and necessary NOT to). And, if I do require it, how can I explain the (in my opinion) sloppiness they sometimes see in online communities?</p>

CC BY-SA 3.0
2018-04-30T13:29:07.943Z
Code on SO is not necessarily "sloppy". Often the type, and other information is "noise" and the OP has created an [MCV example](https://stackoverflow.com/help/mcve).
Gypsy Spellweaver
CC BY-SA 3.0
2018-04-30T14:11:58.837Z
Code on SO is not _necessarily_ sloppy, but it is _sometimes_ sloppy, IMO, and not just when it has been simplified for posting or answering.  The problem is that SO is perceived by beginners as the be all/end all for programming, and they will copy code from there with absolutely no question.  They have not developed the sophistication of a filter based on education and experience.
Java Jive
CC BY-SA 3.0
2018-04-30T14:16:14.983Z
Maybe they need to be introduced to the [Code Review](https://codereview.stackexchange.com/) stack as well. That ought to give them a view to the differences between clear/muddy code. (Code golf serving as examples of _muddy_.)
Gypsy Spellweaver
CC BY-SA 3.0
2018-04-30T21:43:45.393Z
Does `Object x` really do type inference in C#?!
Bergi
CC BY-SA 3.0
2018-04-30T22:07:13.757Z
I wrote some code to verify this but can't figure out how to put it in a comment.  Yes, if I create an Object and assign it an integer, when I call the number's GetType, it returns System.Int32.  If I create an Object and assign it a string and call GetType, it returns System.String.  Same with a programmer-defined class.
Java Jive
CC BY-SA 3.0
2018-04-30T22:21:27.750Z
@JavaJive, IIUC `GetType` gets the type of actual, runtime _value_, so it obviously has to work. That is different from type inference, which is about type of _variable_.
Frax
CC BY-SA 3.0
2018-04-30T23:00:47.533Z
Btw, is VB unavoidable? Perhaps that's just prejudice, but my experience with it (with Xojo, but basic syntax is the same) was rather a struggle. The syntax is overloaded with clutter, and on the my list of least readable and intuitive languages it lands very high. I think it also forces people to declare types (with long names) whether it makes sense or not, which may actually work against you (typing is mostly frustrating and not useful). Maybe I'll elaborate in an answer.
Frax
CC BY-SA 3.0
2018-05-01T11:57:31.993Z
@Frax, VB is unavoidable because it is the required language for progarmming I in my state.
Java Jive
CC BY-SA 3.0
2018-05-01T19:09:05.277Z
If you declare an `Int32` as `Object`, you've just boxed a value type, which is terrible sloppy coding with real performance implications. If you declare an `Int32` as `var`, all you've done is shift the reader's focus on the parts of the code that actually matter, as opposed to making your C# read like Java. FWIW you shouldn't even need to mention `var` until you're ready to get into anonymous types and LINQ. Also, hover the mouse over `var`, the IDE tells you what the compiler type is. `var` has NOTHING to do with `Object` whatsoever. And it's NOT dangerous, even less "sloppy".
Mathieu Guindon
CC BY-SA 4.0
2018-05-02T00:33:29.127Z
Object does not infer types. You can try assing an int to an object variable and then assing an string to the same variable, and it has no problem with it. On the other hand, if you declare with var and assign an int, it is an int, you won't be able to assign a string to it. Using var everywhere is not that bad, really. Object is very bad, because you lose all the static checks, the intellisense, and performance is worse, in particular with value types. So, do not treat Object and var as similar.  Also, x and y are not good variable names, I get it is an example, give good example to students.
Theraot
CC BY-SA 4.0
2018-05-02T09:13:50.480Z
You confirmed that use of var is up for contention, including a link to the discussion, then you immediately say that they **must** use the type "because using `var` is 'sloppy'" (exlcuding previous comment discussion concluding using `object` is actually **wrong** not "sloppy").. So you don't actually *believe* that there is a choice in the industry and you're trying to **force your belief** on your students rather than provide all the information.  This is not a good approach.
fdomn-m
CC BY-SA 4.0
2018-05-02T10:45:09.757Z
Step 1: make the students understand the downsides of down-casting. Step 2: Show the students that using Object forces the use of of down-casting. Additionally: explain var vs object and the run-time performance impact of boxing and type checking
Emond
CC BY-SA 4.0
2018-05-02T12:50:47.033Z
I don't know enough about C# or Visual Studio : still, couldn't you use IDE features for autocompletion or refactoring that work much better (or at all) when every variable is properly defined? Or display warnings when typing `Object x = new Horse("Silver");`?
Eric Duminil
CC BY-SA 4.0
2018-05-02T14:45:33.827Z
I bet you could come up with a good assignment where you give them some bad code to start with (compiles but has run time errors) and tell them to implement x feature starting from that code base (and oh by the way, fix any errors they find)... then let them figure out why it's bad all on their own, when they have a headache trying to debug it.
user3067860
CC BY-SA 4.0
2018-05-02T21:46:06.373Z
@EricDuminil, as far as I know, the IDE is not fine-grained enough to allow you to define what types of variable declarations are acceptable.  But I will look into it.  That's a great idea.
Java Jive
CC BY-SA 4.0
2018-05-02T21:54:19.737Z
@freedomn-m, As an educator, I must have certain expectations in my classroom.  However, in no way do I want to "pull the wool" over my students' eyes.  They know about the controversy surrounding var because I told them and asked them to read about it.  They can meet my expectations and still form opinions.  If they wish to abandon my teaching later, then that is their prerogative.
Java Jive
<data-types>
Once implicit/inferred typing is introduced, how can I impress upon students the importance of not abusing it?
# Once implicit/inferred typing is introduced, how can I impress upon students the importance of not abusing it?

(Asked by: username_0 on 2018-04-30)

I typically have the same students two semesters in a row, for programming I (VB.NET) and programming II (C#). In our early, impressionable time together, I stress to these students (high-schoolers) and show them by example (I write lots of code for them) the importance of writing clear, readable code, which is partly achieved by explicitly specifying types for all variables (at first I do not tell them there are other options)

However, at some point, I have to reveal to my students that they can, indeed, declare a variable as an **Object** (i.e. `Object x = new Horse("Silver");`) and that it can hold anything; or, that they can declare a variable as **var** (i.e. `var y = "foo";`) and that the compiler will figure out what type it is. Some of them discover this on their own, of course.

Then I inevitably have students who abandon the good habits they had formed and want to make everything an Object, or declare everything as var (note I realize this is not equivalent in the language, but students tend to abuse the usage in the same way). I am always torn about how insistent to be that they revert, because I know the use of var in C# is controversial in the industry. (See the SO discussion [use of var in C#](https://stackoverflow.com/questions/41479/use-of-var-keyword-in-c-sharp) for an example). Plus, the more savvy students are hanging out in SO anyway, and they see some questions and answers that lack explicit typing and other good programming habits.

My question is, since these students are still learning, and since it is my classroom after all, should I emphatically require that they always explicitly specify types unless absolutely necessary? (Of course, sometimes it is justifiable, preferred, and necessary NOT to). And, if I do require it, how can I explain the (in my opinion) sloppiness they sometimes see in online communities?

**Tags:** data-types

> **Comments:**
> **username_1**: Code on SO is not necessarily "sloppy". Often the type, and other information is "noise" and the OP has created an [MCV example](https://stackoverflow.com/help/mcve).  
> **username_0**: Code on SO is not _necessarily_ sloppy, but it is _sometimes_ sloppy, IMO, and not just when it has been simplified for posting or answering.  The problem is that SO is perceived by beginners as the be all/end all for programming, and they will copy code from there with absolutely no question.  They have not developed the sophistication of a filter based on education and experience.  
> **username_1**: Maybe they need to be introduced to the [Code Review](https://codereview.stackexchange.com/) stack as well. That ought to give them a view to the differences between clear/muddy code. (Code golf serving as examples of _muddy_.)  
> **username_2**: Does `Object x` really do type inference in C#?!  
> **username_0**: I wrote some code to verify this but can't figure out how to put it in a comment.  Yes, if I create an Object and assign it an integer, when I call the number's GetType, it returns System.Int32.  If I create an Object and assign it a string and call GetType, it returns System.String.  Same with a programmer-defined class.  
> **username_3**: @JavaJive, IIUC `GetType` gets the type of actual, runtime _value_, so it obviously has to work. That is different from type inference, which is about type of _variable_.  
> **username_3**: Btw, is VB unavoidable? Perhaps that's just prejudice, but my experience with it (with Xojo, but basic syntax is the same) was rather a struggle. The syntax is overloaded with clutter, and on the my list of least readable and intuitive languages it lands very high. I think it also forces people to declare types (with long names) whether it makes sense or not, which may actually work against you (typing is mostly frustrating and not useful). Maybe I'll elaborate in an answer.  
> **username_0**: @username_3, VB is unavoidable because it is the required language for progarmming I in my state.  
> **username_4**: If you declare an `Int32` as `Object`, you've just boxed a value type, which is terrible sloppy coding with real performance implications. If you declare an `Int32` as `var`, all you've done is shift the reader's focus on the parts of the code that actually matter, as opposed to making your C# read like Java. FWIW you shouldn't even need to mention `var` until you're ready to get into username_14 types and LINQ. Also, hover the mouse over `var`, the IDE tells you what the compiler type is. `var` has NOTHING to do with `Object` whatsoever. And it's NOT dangerous, even less "sloppy".  
> **username_5**: Object does not infer types. You can try assing an int to an object variable and then assing an string to the same variable, and it has no problem with it. On the other hand, if you declare with var and assign an int, it is an int, you won't be able to assign a string to it. Using var everywhere is not that bad, really. Object is very bad, because you lose all the static checks, the intellisense, and performance is worse, in particular with value types. So, do not treat Object and var as similar.  Also, x and y are not good variable names, I get it is an example, give good example to students.  
> **username_6**: You confirmed that use of var is up for contention, including a link to the discussion, then you immediately say that they **must** use the type "because using `var` is 'sloppy'" (exlcuding previous comment discussion concluding using `object` is actually **wrong** not "sloppy").. So you don't actually *believe* that there is a choice in the industry and you're trying to **force your belief** on your students rather than provide all the information.  This is not a good approach.  
> **username_7**: Step 1: make the students understand the downsides of down-casting. Step 2: Show the students that using Object forces the use of of down-casting. Additionally: explain var vs object and the run-time performance impact of boxing and type checking  
> **username_8**: I don't know enough about C# or Visual Studio : still, couldn't you use IDE features for autocompletion or refactoring that work much better (or at all) when every variable is properly defined? Or display warnings when typing `Object x = new Horse("Silver");`?  
> **username_9**: I bet you could come up with a good assignment where you give them some bad code to start with (compiles but has run time errors) and tell them to implement x feature starting from that code base (and oh by the way, fix any errors they find)... then let them figure out why it's bad all on their own, when they have a headache trying to debug it.  
> **username_0**: @EricDuminil, as far as I know, the IDE is not fine-grained enough to allow you to define what types of variable declarations are acceptable.  But I will look into it.  That's a great idea.  
> **username_0**: @freedomn-m, As an educator, I must have certain expectations in my classroom.  However, in no way do I want to "pull the wool" over my students' eyes.  They know about the controversy surrounding var because I told them and asked them to read about it.  They can meet my expectations and still form opinions.  If they wish to abandon my teaching later, then that is their prerogative.  

---

## 9 answers

### Answer by username_11 on 2018-04-30. Score: 27

> Then I inevitably have students who abandon the good habits they had
> formed and want to make everything an Object, or declare everything as
> var.

These are very different situations. As you observe, the use of `var` in C# is controversial, but using `object` as the type of all variables (and then needing to cast any time you want to actually *use* the variable) is not controversial: it's just wrong.

The first page of answers on the linked SO question about `var` in C# is incomplete. It doesn't mention that using `var` can avoid bugs due to typing in one edge case: `foreach (var foo in foos)` vs `foreach (Foo foo in foos)`. For legacy reasons, if `foos` is a `System.Collections.IEnumerable` but not a `System.Collections.IEnumerable<>` the latter is equivalent to `foreach (Foo foo in foos.Cast())`, which is not especially obvious. (In fact I misremembered and was corrected in comments, which reinforces the advantage of using `var` here).

TL;DR: blanket prohibitions on `var` are almost certainly going too far.

> My question is, since these students are still learning, and since it
> is my classroom after all, should I emphatically require that they
> always explicitly specify types unless absolutely necessary? ...
> And, if I do require it, how can I explain the (in my opinion)
> sloppiness they sometimes see in online communities?

`var` is far from the only controversial subject in programming praxis. The solution in industry is the style guide: whether as a formal written document or as an informal internalised set of opinions which are imparted to new team members by word of mouth when they submit changes which violate the house style. If you're explicitly preparing your students for industry, it is perfectly reasonable to dedicate a bit of time to explaining the concept of the house style, and then when you introduce new material to explain the house style you will enforce for that feature.

The really heavy-duty approach would be to prepare a full industry-style style guide and then to produce a series of increasingly large subsets so that every couple of weeks you can give them a link to an updated style document which specifies how to use the new features you just introduced, or the new features you're about to introduce, and highlights the additions from the previous one.

> **Comments:**
> **username_0**: Yes, the overuse of Object/var are different situations, but in my experience the tendency for new(-ish) programmers to resort to their use in laziness is about the same.  I do mention to them that a style guide will probably be present in their careers and that they should plan to conform to it.  Having a written one for my classroom would be good practice for that.  Maybe I'll get them to write it!  
> **username_1**: Often enough the style guide is _not_ about making the program, in its initial state, better, or the programmer's job any easier. It is, however, about making the "clarity" clearer for any programmer who later deals with that code, including the author. Few rules in style guides are based on rules in the language, but rules in the praxis of the author(s) of the guide.  
> **username_15**: `foreach (Foo foo in foos)` is somewhat equivalent to `foreach (Foo foo in foos.Cast<Foo>())`. It will throw `InvalidCastException` not filter by actual type like `OfType<T>`.  
> **username_16**: Why write your own style guide?  Use the one that is official to the language.  
> **username_11**: @username_16, that's a fair point (when one exists), but it would create copyright problems with the subsetting, and dumping a full style guide which talks about features you won't mention for 3 months is not ideal.  

---

### Answer by username_21 on 2018-04-30. Score: 8

Introducing these sorts of shortcuts can cause exactly the problem that you've outlined.  "Oh, goody!" says the misguided student, "Now I can stop worrying about the type!"
There are a few principles that I directly teach, and repeat extensively in my instruction:

There are two audiences for code, machines and people.  We need to create code that is good for both.
Compiler errors are better than runtime errors.  (This is hard for kids to understand at first, but I return to this idea repeatedly until it is thoroughly drilled into their heads.)
All code must be written with the Four C's in mind: Clarity, Clarity, Clarity, and Clarity.

It has never particularly occurred to me to illustrate that every variable could be declared an Object instead of with a more specific subtype, but the following terrible code could illustrate the dangers of doing this.  (This is in Java, but could just as readily be created in C#):
/* Pre-condition: Object[] passed in is length >= 1
 * arrange puts an Object into o[0];
 */
public void arrange(Object[] o){
    int rand = (int) (Math.random()*4);
    if (rand == 0)
        o[0] = "This is a String!";
    else if (rand == 1)
        o[0] = new Integer(37);
    else if (rand == 2)
        o[0] = new Double(3.1415926);
    else {
        o[0] = new Object[1];
        arrange((Object[]) o[0]);
    }
}

Of course, code like this should make us want to puke just a little bit into our mouths.  We'd ideally want the compiler to stop us.  and that's the key point: declaring variables as Object removes our beautiful compile-time protections, and leaves both the coder and other human readers adrift.  Sure, it's an Object, but what in the world is it?
Similarly, with var, you can borrow some examples from the very page you linked to illustrate why var can be a bad idea.  I also might not introduce the concept until you have introduced Generics, as that is one of the first times that it can actually make things easier.  This would allow you to couple the example of where it can make things easier with examples of where it also can make things insanely more difficult (the more over-the-top, the better for your illustrating purposes).  This will enable you to have a discussion about appropriate usage based on real principles, not just course policy.  
After this discussion, you can explain where you will accept these in your course, and there should be little resistance from your students.  After all, what you are asking for is simply sensible.  Hopefully, this will allow you to create some balance in the lab work you receive.

> **Comments:**
> **username_22**: I remember when C♯ and Java were like this. Containers were containers of Objects (except arrays).  
> **username_20**: I think point #2 is one of the most important, and it's one that I wish language designers would pay more attention to.  If there are two things a piece of code might plausibly be intended to mean, and if a slight adjustment would make the intent unambiguous, having a language require that a programmer be explicit in both cases may be better than having it allow one to be implicitly assumed.  From a teaching perspective, though, I think the issue is probably that if one fixes all the underlying problems that could lead to compile errors, one may be close to having a working program, and...  
> **username_20**: ...this in turn wants causes students to want to reach the point of having their program compile successfully as soon as possible.  What's important for them to learn is that there are ways of making programs compile successfully without fixing their real problems, but if one uses such approaches the real problems will still remain.  
> **username_23**: @username_22 I remember when golang was like that... oh, wait...  

---

### Answer by username_17 on 2018-04-30. Score: 6

If I learned anything reading Dale Carnagie, if you want to convince someone to do something, don't tell them "Do this because I want you to," tell them "Do this because if you don't, you're going to suffer for it and it's your loss." Speak in terms of their own self interest.

You might want to tell them, "Now, you may want to use Objects for everything. This is bad and it will suffer because of it. You'll get weird errors when you start using it. If you don't want to spend 30 minutes debugging a program for a silly error, don't use Object like that. Here are some examples of using Objects will make your life more painful..."

As far as using var for everything, I'm a professional programmer and I use var all the time. I can't help you there (if I were one of your students, I would wonder why I couldn't work more efficiently either!). It's important to know what type you're working with, but as long as you do that, *var* away.

> **Comments:**
> **username_0**: I am/was a professional programmer too, and I always use types when I declare.  The only place I think var is justified is when working with LINQ queries and their results (foreach var...).  Efficiency now causes headaches later.  
> **username_17**: @JavaJive That's fine... it's ultimately a matter of debate. But honestly, as a mildly rebellious student myself I would have chafed under required "vars" if there isn't an airtight case for them (which there isn't). Then again, I don't know much about teaching so I can't say when you should lay down the law and when you should back off.  

---

### Answer by username_18 on 2018-04-30. Score: 5

If you expect that many of the students will pursue software development careers, it would not be unreasonable to declare style standards for the course, and include it in their grading.

When doing so, I strongly recommend explaining *why* particular rules are in place, because it moves disagreement into "arguing principles" instead of having "arbitrary rules".

The explanation could be as simple as "we're going to follow the [corefx style guidelines](https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md)" because the majority of example code produced by the .NET development team will adhere to these rules.

> 10. We only use `var` when it's obvious what the variable type is (e.g. `var stream = new FileStream(...)` not `var stream = OpenStandardInput()`).

Or, the rules could be a bit more esoteric/practical. As a grader many years ago I got the professor to agree to a style score as a portion of the coursework. I told the class "I will be reviewing your code with the program `less` in an 80-character wide terminal. If I have to horizontally scroll you will get 0 points for style." -- I think I gave a 0 for breaking that rule just once.


---

### Answer by username_19 on 2018-04-30. Score: 5

There are a number of issues to be addressed from clarity of the written code to efficiency of the compiled code. For beginners, I think the clarity issue is more important so I'll address that first. 
Before I begin, though, I'll also note that the inferred typing of variables in C# is still static (compile time), strong (types don't change) typing. That hasn't changed. Inferred typing is just a syntactic hack (syntactic sugar) that appear to make the programmer's job easier. However, that is only true when you are writing the program the first time, not when you are updating/modifying/maintaining the program. 
I'll note also, that programming languages are for people, not for computers. Compilers take the human-understandable code that we write and transform it into something that a machine can utilize. 
Specifying the type of a variable in a declaration, while not always required introduces a kind of good redundancy. Much redundancy in programming is bad (repeating a sequence of statements) but redundancy in typing is good since it makes the intent of the programmer clearer and also, in some situations finds errors in a program at compile time that could otherwise only become noticeable at run-time. This lets the programmer fix issues earlier in the development process, which, research shows, reduces cost. 
Think of the phases of program development as follows: conceptualization, analysis, design, coding, testing, deployment, maintenance (maybe not a universally agreed list, I realize). Research shows an order of magnitude increase in the cost of correction for each phase transition. If you catch the error in the conceptualization phase it costs nearly nothing to fix. (Sorry, I don't have a reference to the research - it is quite old). 
When you say that a variable is int and later (or immediately) assign it an int value the compiler can check correctness. But you the program reader are also assured that your intent (x is an int) is faithfully represented in the code. 
var x = 5;

reduces the redundancy. Note also that 5 is a valid value of the following C# types: byte, sbyte, int, uint, long, ulong, short, and ushort. What is your intention here. The declaration above doesn't say. The compiler will choose something it "thinks" is appropriate. By saying less about your intent you give less information to the compiler, which may then provide a less-than-optimal translation of your code. So this sort of redundancy is a good thing. 
When used with objects (or otherwise polymorphic types) there is an additional consideration. 
If you say
var x = new Horse("Trigger");

then the compiler has little recourse than to give x the most specific possible type. It might, in fact be preferable to give x a more general type, such as an interface type used to create the Horse class. It is generally good programming practice to give variables interface (as opposed to class) types, though this requires other rules about how interfaces are used - a separate discussion. But, in some contexts
Animal x = new Horse("Trigger");

might be preferable and it also better clarifies your intent.
None of the above uses of var is necessarily a mind-killer, but an alternative use of what I want to call sloppy typing is. 
Suppose you declare a new object reference as follows:
Object x = new Horse("Trigger");

Now you have likely introduced a mess into your program. Later on, you will probably want to say
int howMany = x.count();

(We know, horses like Trigger can count, of course). The compiler will complain about this, of course since x is only known as an Object reference, not a Horse reference. The sloppy typer will then cast x to quiet the complaints of the compiler:
int howMany = ((Horse)x).count();

which is, of course ugly. We need to assure the compiler that x is, indeed, a Horse so that the count method is available. However, this cast introduces a check into the runtime code, which is both inefficient and can be wrong. What if somewhere else prior to this x was reassigned to an Aardvark object. Then whether or not Aardvarks can count or not, the run-time type check will flag an error. 
This sloppy typing combined with casting is an attempt to replace the normal static type checking with dynamic type checking (as is done in, say Python). But that is misuse of the language. 
Moreover, it introduces a maintenance nightmare into your program. You declare a variable in your program to have a given type, but in use it has a different (more specific) type. The compiler isn't going to remember those actual types for you, so you have to do this yourself. You can't look back to the declaration of x to find out what sort of thing it represents, you have to keep the details of the dynamic system in mind for every use of the variable. In a program of any size this is obviously infeasible. It is why we have types (and also polymorphism) in the first place. 
Again, this sort of casting (down casting) is a recognized Code Smell, indicating poor design. Every explicit cast in a program is a potential point of error. Just Say No. 
For completeness, let me give a few rules here that will lead to better design and better code. 

When you declare a variable give it an interface type (rather than a class type) - a good but not essential rule. Interfaces define concepts. 
When you implement that interface the only public methods of the class should be those defined in the interface. You won't need to cast. - an essential rule.
When you extend a class (create a subclass) the only public methods in the subclass should be those declared in the superclass. Essential. If you need more methods then you have a different concept than the superclass, so extend the interface of the original class to define the new concept and then have the subclass also implement the new interface. 
When you declare a variable to have some (object) type, don't try to send messages defined only in some subtype, requiring casting. 

The above rules are intended to make your programs easier to understand, hence easier to update and maintain. When tempted to break the rules, spend a bit of time asking why, and looking to see if you can come up with a better design. Breaking the rules tends to make your overall program into a Big Ball of Mud.
All of the above has focused, primarily, on clarity of the code for the programmer's benefit. But efficiency is also a consideration. 
The more you can inform the compiler of your intent, the better job it can do in its translation. Some languages optimize for expressing intent rather than process, in fact. Database languages and Logic languages do this explicitly. If you tell a compiler how to do something it will be constrained to follow your directions. But if you tell it what you want, rather than how to achieve it, it has more options and can do better optimizations. So, explicit typing in programs is also a way to communicate intent (what) to the compiler rather than forcing later checks (casts). So, maybe x in our first example really only needs to be a short, or even a byte. But the declaration using var probably won't achieve that. 
I also realize that "abstract" names like x are a poor choice. I only use it here as I don't have a context in which to provide an intention revealing name. 

History note:
Implicit typing is probably an incorrect term for this. FORTRAN had implicit typing where the type of a variable depends on the spelling of the name. Names beginning with I through N were implicitly Integer unless a specific declaration implied otherwise. Other names indicated Real variables. 
On the other hand, Standard ML and related languages have a subsystem in the compiler that could infer types (type inference). ML has strong static typing also, but programmers seldom need to specify a type since the compiler can ordinarily figure it out. 
But use of var isn't dynamic typing either. In dynamic typing (Python, Ruby), variables (names) don't have type. Only values have type. Dynamic typing can still be strong typing, but it is done at run-time, not compile-time. Errors are found later unless they are rigorously rooted out through testing during development. 

Final Note:
The biological classification of Carl Linnaeus is probably a poor analogy to use for subclassing and polymorphism. Each entry in the classification tree is a different concept and all are abstract. There is no such thing as a pure Mammal. Moreover, classes define behavior of objects (via public methods) and the Linnaeus classification system is nothing about behavior. Trying to use it to generate examples of subclassing is one of the reasons students get terrible ideas about what should be done in a subclass.

> **Comments:**
> **username_20**: Variables can be used either to represent values or containers.  One could use a value of type `Horse` which identifies a `Horse` just about anyplace one could value of type `Animal` that identifies a `Horse`, but a *container* of type `Horse` which will always a `Horse` any time it's not null is very different from a container of type `Animal` which *initially* identifies a `Horse`, but might later identify a `Dog`.  
> **username_19**: @username_20, sorry, not sure how you are using the term _container_ here. Are you contrasting reference (i.e. heap) values from others?  
> **username_20**: If I say `int x=someComputation();` and never write to `x`, then within its scope `x` would be synonymous with the value yielded by that call to `someComputation`.  If instead I say, `int x=0;` and later within a loop say `x+=someOtherComputation;`, then there would be no particular value with which `x` would be associated throughout its scope.  Instead `x` would be used as a place to store computations which are performed throughout its lifetime.  
> **username_19**: @username_20, If you have some way to specify that x is a constant (const in C++, final in Java, etc) then yes. Otherwise the system will treat both the same and it is only your intention that makes them different.  
> **username_20**: The system will treat both the same, true.  On the other hand, programs are usually intended to be read not just by computers but also by people.  
> **username_19**: @username_20, that isn't the point. If the restriction can't be communicated nor enforced it doesn't _really_ exist. The next person to read the program won't understand it or be bound by your intention during maintenance. The code itself should express your intention. Comments can help a bit, but they have to be read and agreed to. Make the code express the intention.  

---

### Answer by username_10 on 2018-05-02. Score: 1

Then I inevitably have students who abandon the good habits they had formed and want to make everything an Object

This can easily be shown to be a bad approach if you need a class specific property later on.
object myStudent = new Student("John", "Doe");

string name = myStudent.Name; //doesn't work

They'll probably use a hard cast, at which point the issue is no longer that they use object, but that they are losing out on type safety.
The problem here is that an adequately skilled student who is ahead of the curve will always be able to work around simple pitfalls. If he is overskilled for the example, he has more than enough brainpower to ensure that his hard casts always work.
The only way to force them to make mistakes is to give them a sufficiently complex example, where they're struggling with the core intention so much that having to manage hard casts on top of that just makes everything so much worse.
But you may have to single them out for this complex task; which can in and of itself signal that they don't need to complete this hard task (since you can't just make tests harder for a particular student).
The only guaranteed solution is to explicitly disallow hard casting in the problem statement.
Any other (more implicit) approach is liable to be a cause for complaints when the student loses grades over this.

I am always torn about how insistent to be that they revert, because I know the use of var in C# is controversial in the industry. (See the SO discussion use of var in C# for an example). 

Your conclusion does not match your observation. Suppose the community is split 50/50 between either using var freely, or not using it at all. That means that either choice is equally correct.
Standards and conventions are, unsurprisingly, decided by convention.
The only things you should be telling your students to not do are the things that a majority of the community agrees are bad approaches (such as hard casting for no good reason).

This goes even further. var may actually be the solution to your object-focused students. In all likelihood, they are choosing the blanket use of object because they find it unnecessarily hard to always write the correct type. var solves that problem by having the compiler (not the developer) figure out the types that are trivial to look up. 
You're seeing this as two similar issues, but it's much more likely that one (object) is a consequence of your reluctance to allow the other (var).


Plus, the more savvy students are hanging out in SO anyway, and they see some questions and answers that lack explicit typing and other good programming habits.

This is again a matter of convention. If students are predominantly exposed to "StackOverflow code quality", then it makes sense for them to adapt "StackOverflow code quality". 
Being better than your surrounding is not always objectively better. The first company I worked in was comprised of self-taught developers and one university graduate. His solutions were much more theoretical than ours. But he couldn't make those solutions work in our company, because everyone else disagreed with him.  
While I'm not in any way arguing that CS theory is bad; you do need to realize that pretty much every argument of code quality rests on convention, not objectively provable superiority. If something were actually illogical or inferior, then no one would keep advocating its use, thus eventually rendering it outdated.
What you're trying to do, with the best of intentions, can also be construed to be bordering on requiring students to adhere to your preferred standard as opposed to the average community standard.

My question is, since these students are still learning, and since it is my classroom after all, should I emphatically require that they always explicitly specify types unless absolutely necessary? 

As a teacher, it is your prerogative to be selective about what you consider a correct answer. However, if you are requiring a particular standard to be upheld, then you should explicitly mention this.
If you ask your students for "an application that does [thing]", then you're implying that any working code is a correct answer to the question (which deserves full marks).
If you ask your student for "an application that does [thing] and avoids string concatenation (+)", then you've made it clear that working code that uses string concatenation is not a correct answer to the question.
If you want to force a particular answer, you must phrase your question accordingly. Do not punish students for an implicit convention, because most students expect questions that reveal how their answer will be graded.

And, if I do require it, how can I explain the (in my opinion) sloppiness they sometimes see in online communities?

"Just because it works, does not mean it works well." is what my teacher used to tell me. And I was the kind of student who needed to repeatedly be told that.

(Of course, sometimes it is justifiable, preferred, and necessary NOT to). 

Just out of curiosity, when is var ever a necessity? I can't think of a single case. As far as I'm aware, var is merely shorthand, not an actual technical benefit.

> **Comments:**
> **username_11**: `var` is absolutely necessary in some contexts with username_14 types, which AIUI was one of the motivations for introducing it. My answer to this question also mentions a situation (`foreach` loops) where getting into the habit of using `var` always will allow the detection of problems at compile-time rather than runtime.  

---

### Answer by username_14 on 2018-04-30. Score: 1

There are a few reasons why this is bad, for example it could lead to code issues down the line where you need something from `Horse` that you don't have on `Object`, and it may also be a code smell. I'm going to suppose the code passes and runs fine, the architecture is fine, and just focus on the remaining issue: the issue generally is of course that it's not as specific as it could be, and the reason that's bad is it's bad for maintainability and code clarity.

In general, for maintainability, you want your code to model your ontology, to be resilient to counterfactuals. That way, if things need to change in the future, your code will more likely be constructed in a way thats amenable, because even though certain specifications changed, or some refactoring is being done, your code is still basically modeling the logic of the situation.

So `Object x = new Horse("silver")` is bad because `x` is not just an `Object`, it's a `Horse`, maybe it's an `Animal`.

(1) You lose the code clarity, future readers won't have the info of immediately knowing, if they want to change the value of `x`, what `x` "is" and a sense of how it's going to be used.

(2) You lose benefits of type-checking, because anything using `x` only knows it's an `Object` and doesn't know it's a `Horse`.

I'm not a teacher, I'm just a programmer in industry, but I think maybe the single most important general principle I use in my day to day is: code should model ontology, including in the sense that it's robust to counterfactuals. A lot of bad code falls under that category.


---

### Answer by username_12 on 2018-04-30. Score: -1

Various forms of the same question to ask oneself:

* Does this "thing" represent part of my design?
* Is it a key aspect of a contract?
* Do I want to *anchor* my thinking around a specific type at this point in my code?

In all cases a strict type declares to my reader (myself in 6 months) that this is important. If it's less important, let it go.

---

*an implicit reference to a Disney movie is not explicitly declared, so it's not an anchor point for my argument.*


---

### Answer by username_13 on 2018-04-30. Score: -2

Teach them c/c++ first, or go into the common uses of each data type first so they have to understand the intrinsic properties.


---

