Click here to Skip to main content
15,892,746 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Dear Guys ..
iam new to in dot net iam studying c# generic.. please verify and solve my below program.. i need to study c# Constrains.. please help me

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program<T>
    {
        T a, b, c;

        public T add(T m,T n)
        {

            return  m + n;///this statement is an error in vs
        }
    }
    class demo
    {
        static void Main(string[] args)
        {
            Program<int> ob=new Program<int>();
            Console.WriteLine(ob.add(10,9));
        }
    }
}
Posted
Comments
Andreas Gieriet 17-Jan-12 6:10am    
You can't fix it by simply adding a constraint for T. Take for example the int type: it has no + in its interface nor does any of its interfaces define it. + is built-in for the built-in numeric types. Therefore, you can not any constraint that would allow to call + on the T values mapped to int.

Off topic: you might use (dynamic)m + (dynamic)n, but this is not type-safe - it works by reflection and throws a Runtime Exception - in stark contrast to generics which are type-safe code generators. So, don't use dynamic when ever possible.
johannesnestler 17-Jan-12 7:21am    
My solution used dynamics because I don't see a nice Interface implementation for this. But I agree on avoiding any form of RTTI, and avoid it in real life whenever possible (I come from c++, COM... so sometime I needed it). You seem to be a fan of strongly typed languages - like me - but other may disagree... (I guess someone likes the DLR?). Conclusion: OP stated problem is homework, so I think my solution is Ok for this, but thank you for pointing to the problem with this aproach.

Hi irfad,

There is no "operator" constrain possible in c#. But what you could do (since .NET 4) is using a dynamic type and cast your <t> parameters to it.
Better I show an example:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program<T>
    {
        T a, b, c;

        public T add(T m, T n)  
        {      
            dynamic dm = m;
            dynamic dn = n;
            return dm + dn;
        }
    }
    class demo
    {
        static void Main(string[] args)
        {
            Program<int> ob = new Program<int>();
            Console.WriteLine(ob.add(10, 9));
        }
    }
}


But watch for proper exception handling! -> If at runtime the type <t> supports no "+" operator the code throws a (RuntimeBinder-)Exception.
You can see it like this: dynamic just tells the compiler to "shut up", because I (=the programmer) know this will work at runtime - but make shure thats true! :-)
 
Share this answer
 
v2
Comments
ambarishtv 17-Jan-12 5:50am    
My 5 :-)
Amir Mahfoozi 17-Jan-12 6:17am    
+5 well done.
BobJanova 17-Jan-12 7:34am    
Does that compile? I'd think the cast of (dm+dn) to T would fail.

Using dynamic loses you a whole load of type safety and you might as well just declare the parameters dynamic and not bother with the generic at all, I'd say.
johannesnestler 17-Jan-12 10:04am    
You are correct, dynamic has it's drawbacks (look @ my comments). But the solution works, is compilable and tested.
Check this[^] page. It should help. The treeview on the left has a lot of material for generics. Have a look at that too. HTH
 
Share this answer
 
Unlike templates in C++, you can't use generics to call a language defined operator. This is rather annoying because it's the first thing that anyone tries, and what's more the base numeric types don't implement an INumeric interface or anything that would provide a workaround.

Here's as simple an example of a constraint as I can come up with:
class Combiner<T>  where T: ICombinable {
 public T Combine(T a, T b) { return a.Combine(b); }
}

interface ICombinable {
 object Value { get; }
 ICombinable Combine(ICombinable b);
}

class Combinable : ICombinable {
 public object Value { get; set; }

 public Combinable(object value) { Value = value; }

 public ICombinable Combine(ICombinable other) {
  ArrayList al = new ArrayList();
  al.Add(Value);
  al.Add(other.Value);
  return new Combinable(al);
 }
}

// And using it
class Starter {
 static void Main(){
  Combinable one = new Combinable(1), two = new Combinable(2);
 
  var combiner = new Combiner<Combinable>();
  Combinable result = combiner.Combine(one, two);

  Console.WriteLine(result.Value);
 }
}


Without the bolded constraint in the definition of Combiner<T>, you couldn't use any methods on T within that dlass (beyond the standard methods on object, i.e. GetHashCode, ToString etc). The constraint means that you can only set the type parameter to something that implements the interface you put there, e.g. Combiner<int> would be an error because int doesn't implement ICombinable, and therefore you can safely use ICombinable methods (i.e. Combine) within the Combiner<T>.

The rest of the code is just defining some code that actually does something so you can make a runnable example of it, I've deliberately stayed away from generics except for the very simple Combiner class with a constraint on it.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900