First, if you are a not familiar with generics, or would like a refresher course, check out “Overview of Generics in the .NET Framework” at http://msdn2.microsoft.com/en-us/library/ms172193

For overview on templates, visit http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_templates_in_c.2b2b3a_.overview.asp

Now, the answer to the question on the topic line is “No”.  Yes, they both make it possible to create parameterized types which make it possible to create type safe collections. But…

1. Templates are instantiated at compile-time.   Generics are instantiated at run-time by the CLR.   This leads to the fact, that generics could be instantiated cross assemblies, even cross-language, while it is just not possible to instantiate a template from another assembly.

2. Templates allow user-defined specialization, i.e. in the example below there are four instantiations and three specializations:
    Collection<int> a;
   Collection<int> b;
   Collection<double> c;
   Collection<X> d;

But generics, cannot be specialized -- you can write it only once, which is equivalent to writing a primary template.

3. Templates allow non-type parameters (e.g. integers), which serve as constants within instantiations of the class, e.g.
    template <class T, int size>
    class MyCollectionClass {
    . . .
    }

Generics do not allow this type of syntax.

4. Generics support subtype constrains, e.g.
    generic<typename T>
          where T : IG
          ref class R {
            void f(T t) {
              t->g();
            }
          };

5. With templates, constraints are enforced at specialization.  With generics, overload resolution is done at the point of definition.
      interface class IMethod {
        void f();
      };
 
      ref struct R : IMethod {
        virtual void g() = IMethod::f {
          System::Console::WriteLine("R::g");
        }
 
        void f() {
          System::Console::WriteLine("R::f");
        }
      };
 
      generic<typename X>
      where X : IMethod
      void G(X x) {
        x->f();
      }
 
      template<typename X>
      void T(X x) {
        x->f();
      }
 
      void main() {
        R^ r = gcnew R;

        G(r);
        T(r);
      }

With generics, the call to f is done through the interface IMethod. With templates, the call to f is done directly on the class R. Thus, the output of this program is:

      R::g
      R::f


In Summary:

                                                            Generics                                 Templates
Constraint mechanism            
  Subtype constraints               Lazy structural constraints
Allows explicit specialization    No                                       Yes
Allows partial specialization     No                                       Yes
Type identity of specialization Globally unique                      Unique to each assembly
Cross language facility             Yes                                      No
Allowed parameters                 Ref class, value class only      All types and non-type
Name lookup and binding          At definition, to constraints     At specialization, to type


Source: http://blogs.msdn.com/branbray/archive/2003/11/19/51023.aspx