Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Just wondering if I've been missing something all this time.

 

My main use of Generics is like this

List<MyUDT> myItems = new List<MyUDT>(50);

foreach(MyUDT i in myItems)
{
   Console.WriteLine(i.ToString());
}

 

What are some other applications of Generics that you use, or is this the majority of the use?

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

  • Administrators
Posted

Collections are one of the main use of generics, however they can also be useful for utility functions.

 

If you wanted to do a simple Min or Max kind of function for example generics can be useful...

   static class Utils
   {
      public static T Max(T a, T b) where T : IComparable
       {
           return (a.CompareTo(b) > 1 ? a : b);
       }
   }

 

This can be called like

string s1 = "Test", s2 = "Example";

string s = Utils.Max(s1, s2);

int i1 = 3434, i2 = 3322342;
int i = Utils.Max(i1, i2);

but only when a valid comparison exists, otherwise a compile time error is generated.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

Say you have a number of classes (Customer class, TreasuryBond Class, ApplicationForTBond class, etc.) and you want to hold a list of each of the respective instances.

 

One way to achieve that is to create a class for each class: CustomerStack, TreasuryBondStack, etc... Intuitively (naturally), you see a pattern here, namely, the stack. So, why not create a general (hence, 'generic') class that will support any type and will avail the creation and use of stacks for each type?

 

That is, create a generic class:

 

Public Class Stack(Of [b]T[/b])
   Private _items() As T   ''' dynamic array to hold the times of type T
   Private _cnt As Integer  ''' counter

   '''Now define properties and methods. For instance:
   Public Sub Push(item as T)
        ''add code here
   End Sub

   Public Sub Pop(item as T)
        '' add code here
   End Sub
End Class

Posted

PD -- that is exactly the type of information I was looking for. I could have been pithy with my question: "What other use of Genrics is there besides Collections?" but this is a programming forum so I felt obligated to post code.

 

Borix -- For simple implementations couldn't you do ~

Stack<MyUDT> UDTs = Stack<MyUDT>;

void main()
{
   UDTs.Push(new MyUDT(val1,val2));
}

void ButtonClick(...)
{
   MessageBox.Show(UDTs.Pop().val1Prop);
}

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

  • Leaders
Posted

A good place to find different uses of generics is the DotNet framework. For instance, there is a generic delegate type...

public delegate void EventHandler<TEventArgs>(
   Object sender,
   TEventArgs e
) where TEventArgs : EventArgs

This allows you to create an event with any type of EventArgs without declaring a new delegate type.

 

DotNet doesn't come with a generic EventArgs class, but write your own and you'll be able do add all kinds of events to your object without declaring any new types.

[sIGPIC]e[/sIGPIC]
Posted

Generic EventArgs

 

DotNet doesn't come with a generic EventArgs class, but write your own and you'll be able do add all kinds of events to your object without declaring any new types.

 

I've never considered EventArgs to be a good candidate for a generic implementation, since the number and type of event-specific parameters can be so variable. You suggest that you've implemented such a class. Can you show the implementation and how it benefits from using generics?

Never trouble another for what you can do for yourself.
  • Administrators
Posted

Re: Generic EventArgs

 

Assume the following sample has two custom event args that are actually useful, the only way to create the events is to declare two delegates and use these in the event declarations...

   public partial class Form1 : Form
   {
       public delegate void TestEventHandlerOne(object sender, SampleEventArgs e);
       public delegate void TestEventHandlerTwo(object sender, AnotherSampleEventArgs e);

       public event TestEventHandlerOne TestOne;
       public event TestEventHandlerTwo TestTwo;

       public Form1()
       {
           InitializeComponent();
       }
}

   public class SampleEventArgs : EventArgs
   {}

   public class AnotherSampleEventArgs : EventArgs
   { }

 

The generic EventHandler however gives the slightly cleaner...

   public partial class Form1 : Form
   {
      public event EventHandler TestOne;
      public event EventHandler TestTwo;

       public Form1()
       {
           InitializeComponent();
       }
}

   public class SampleEventArgs : EventArgs
   {}

   public class AnotherSampleEventArgs : EventArgs
   { }

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

Generic EventArgs

 

I understand the usefulness of the generic EventHandler delegate. However, marble_eater suggested creating a generic EventArgs class, and I am struggling to see how generics could be useful here.

 

What I end up having to do is basically what you've described in your post with SampleEventArgs and AnotherSampleEventArgs. If there were a way to reduce these into a common generic class, I would be very interested. I just don't see how this could be done without having to impose limitations on the parameters passed within the EventArgs object.

Never trouble another for what you can do for yourself.
  • Leaders
Posted

Re: Generic EventArgs

 

There certainly won't be a generic EventArgs class that can handle all situations, but a small library will cover most situations.

 

C# Code[HorizontalRule]magic hidden text[/HorizontalRule]public partial class Form1:Form

{

····public Form1() {

········InitializeComponent();

········this.label1.TextChanged += new EventHandler(label1_TextChanged);

····}

····void label1_TextChanged(object sender, EventArgs e) {

········// Create a purpose-typed event args object without declaring a new type.

········ValueChangedEventArgs<Label, String> args = new ValueChangedEventArgs<Label, string>();

········args.Target = label1;

········args.OldValue = chachedLabelValue;

········args.NewValue = label1.Text;

········LabelTextChanged(this, args);

····}

····// Create an event without declaring a new delegate type.

····public event EventHandler<ValueChangedEventArgs<Label, string>> LabelTextChanged;

}

// Here we have some event args classes. The important thing

// here is that these can be reused for any DotNet type.

public class TargetEventArgs<T>:EventArgs

{

····private T target;

····public T Target { get { return target; } set { target = value; } }

}

public class ValueChangedEventArgs<TTarget, TValueType>:TargetEventArgs<TTarget>

{

····private TValueType oldvalue,newvalue;

····public TValueType OldValue { get { return oldvalue; } set { oldvalue = value; } }

····public TValueType NewValue { get { return newvalue; } set { newvalue = value; } }

}

[HorizontalRule]Why are you quoting me?[/HorizontalRule]

[sIGPIC]e[/sIGPIC]
  • 3 weeks later...
Posted

Which do you think is better? And more importantly, why?

 

Obviously this first approach is good for simple implimentations while the second lends itself to greater flexibility.

 

What are some reasons you think of that would push a "simple implimentaiton" to a more complex one that might require the added flexibility?

 

..BOL..
public class MyClass
{
...
}

..DAL..
public List<MyClass> GetMyClassObjects(String SearchParm)
{
.....
}

..presentation..
DAL myDAL = new DAL();
List<MyClass> myList = myDAL.GetMyClassObjects("New");
DataGrid.Datasource = myList;
DataGrid.DataBind();

 

Or something like this

 

..BOL..
public class MyClass
{
...
}
public class MyClassList : List<MyClassList>
{
...
}

..DAL..
public MyClassList GetMyClassObjects(String SearchParm)
{
...
}

..presentation..
DAL myDAL = new DAL();
MyClassList myList = myDAL.GetMyClassObjects("New");
DataGrid.Datasource = myList;
DataGrid.DataBind();

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

  • 2 weeks later...
  • *Experts*
Posted

I've used both - a simple return type of List<T> and a class that derives from List<T>.

 

Here's how I decide (if-based, because I'm a programmer :) )

 

If the list is "internal" only - just a quick return type so I can iterate over the list, use the simple List<T> return type.

Else create a class.

 

More often than not, once I have created the class I find a reason to add a method or two.

 

-ner

"I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Posted

Thats exactly the type of response I was looking for, thanks!

 

I had been using a similar approach; so I feel good now that at least one other person shares my logic!

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

Posted

Return interfaces where possible.

 

I always try to return interfaces where possible, so in this example I would return IList<T>. This then allows me to change what object I actually return without needing to redefine the function. I often start with List<T> then change to a custom derived class, or ReadOnlyCollection<T>, depending on requirements.

Never trouble another for what you can do for yourself.
Posted

So in my example above, you would change to something like this?

 

My undestanding of Interfaces is very basic......

..BOL..
public class MyClass
{
...
}
public class MyClassList : IList<MyClass>
{
...
}

..DAL..
public IList<MyClass> GetMyClassObjects(String SearchParm)
{
...
...
return new MyClassList(...);
}

..presentation..
DAL myDAL = new DAL();
MyClassList myList = myDAL.GetMyClassObjects("New");
DataGrid.Datasource = myList;
DataGrid.DataBind();

~Nate�

___________________________________________

Please use the [vb]/[cs] tags on posted code.

Please post solutions you find somewhere else.

Follow me on Twitter here.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...