This question already has answers here:
Closed 13 years ago.
Duplicate of What is the "< >" syntax within C#
Actually i want to know 'why and when should i use generics?'.
What is the need for it?
Generics are a way of ensuring Type Safety at Compile time in C#.
Example- Pre-Generics:
class Person
{
string name;
string lastname;
public Person(string _name ) { this.name = _name; }
}
class ClientCode
{
public static void Main()
{
//create a list of person
ArrayList personList = new ArrayList();
Person p1 = new Person("John");
Person p2 = new Person("Ram");
personList.Add(p1);
personList.Add(p2);
// BUT, someone can do something like:
// ArrayList does not stop adding another type of object into it
object q = new object();
personList.Add(q);
// while accessing personlist
foreach(object obj in personlist)
{
Person p = obj as Person;
// do something, for person
// But it will fail for last item in list 'q' since its is not person.
}
}
}
Example- Post-Generics:
class ClientCode
{
public static void Main()
{
//create a list of person
List<Person> personList = new List<Person>();
Person p1 = new Person("John");
Person p2 = new Person("Ram");
personList.Add(p1);
personList.Add(p2);
// Someone can not add any other object then Person into personlist
object q = new object();
personList.Add(q); // Compile Error.
// while accessing personlist, No NEED for TYPE Casting
foreach(Person obj in personlist)
{
// do something, for person
}
}
}
Generics let you parameterize code over types in the same way that arguments let you parameterize it over values. That probably doesn't explain a whole lot, so lets go through it a step at a time:
Imagine you want a program to print "I like bunnies". You write this:
static void Main()
{
ILikeBunnies();
}
void ILikeBunnies() { Console.WriteLine("I like bunnies"); }
All well and good. But you also like cheese, so now you have:
static void Main()
{
ILikeBunnies();
ILikeCheese();
}
void ILikeBunnies() { Console.WriteLine("I like bunnies"); }
void ILikeCheese() { Console.WriteLine("I like cheese"); }
You notice that your two functions are almost identical. You want to reuse the same function, but provide different values for what you like:
static void Main()
{
ILike("bunnies");
ILike("cheese");
}
void ILike(string what) { Console.WriteLine("I like " + what); }
This is what function arguments are for: they let you reuse the same code with different values.
Generics are like that, but instead of passing in different values, you pass in types. Lets say you've got code that needs to bundle two strings into an array:
static void Main()
{
string[] s = Pair("a", "b");
}
string[] Pair(string a, string b) { return new string[] { a, b }; }
Fine and dandy. Later you realize you also need to bundle ints into an array:
static void Main()
{
string[] s = Pair("a", "b");
int[] i = Pair(1, 2);
}
string[] Pair(string a, string b) { return new string[] { a, b }; }
int[] Pair(int a, int b) { return new int[] { a, b }; }
Just like before, we can see there's a bunch of redundancy there. What we need is a function that returns a pair of whatever and a way to pass in the type of what we want a pair of. This is what generics are for:
static void Main()
{
string[] s = Pair<string>("a", "b");
int[] i = Pair<int>(1, 2);
}
T[] Pair<T>(T a, T b) { return new T[] { a, b }; }
The angle brackets let you pass in a type to a function in the same way parentheses let you pass in values. "T" here is the name of a type argument just like "what" was the value argument above. Any place T appears in the function will be replaced with the actual type you pass in (string and int in the example).
There's a bunch of stuff you can do with generics beyond this, but that's the basic idea: generics let you pass types into functions (and classes) in the same way arguments let you pass in values.
Generics basically remove the need to cast and objects into their base type.
e.g. if you want to store a group of Foos in a List.
You used to have to either create your owen FooList or cast the item as objects.
All this takes you time and the complier.
With Generics all you have to do is sat List it checks you types and speeds up you programs. (no boxing and unboxing)
Suppose you yourself is an algorithm which can sort whatever objects that can be compared pair-wise (playing-cards, CDs, business cards, whatever). You're not actually interested in what these concrete objects are provided you can compare them. Thus you become a generic (here "generic" is used in a broad term, not in C# sense) algorithm.
Generics in .NET help facilitate this particular kind of behavior not only in terms of algorithms (generic functions), but also in terms of generic types (classes, structs, delegates, interfaces).
Just to add to what everyone else will tell you, more practically, try doing something with an ArrayList or System.Array object and then try doing it with a List<T> and you can immediately see the how generics allows you to write more readable code and write it quicker too.
I blogged about it a long time ago, here. I was working with XML, and I wanted a helper that would get an XmlElement or an XmlAttribute (based on an XPath) and let me work with it. It was a nice simple example I worked through in the real world when generics were fairly new to C#.
Related
Case 1 : Covariance in arrays.
object[] array = new String[10];
// The following statement produces a run-time exception.
array[0] = 10;
Case 2 : Covariance in IEnumerable.
IEnumerable<Object> l1 = new List<string>();
// The following line executes just fine.
l1 = l1.Append(33);
We are implementing same scenario, i.e. putting an object of Array/List of more derived type (string), in a variable of less derived type (object), and then trying to add an element of type int.
Another related observation:
Consider we have following set of classes:
public class Bird { }
public class Pegion : Bird { }
public class BirdCalculations<T>
{
private T TField;
public void SetTField(T value)
{
this.TField = value;
}
}
In this scenario, consider the following code:
public static void Main() {
BirdCalculations<Bird> bc2 = new BirdCalculations<Pegion>(); //Line 1
BirdCalculations<Bird> bc1 = new BirdCalculations<Bird>();
bc1.SetTField(new Pegion()); //Line 2
//Now, Line 2 makes sense, but what is the problem with Line 1?
}
If your class is the receiving end of T-type parameter e.g. having method foo(T bar), you need a contravariance of T and not covariance, which is denoted as in T in C#. It also has to be an interface or delegate, so it is not possible to allow assignment of BirdCalculations<T1> instance to BirdCalculations<T2> reference or vice versa or whatever, no matter how T1 and T2 are related. It has to be IBirdCalculation<T1> bc = new BirdCalculation<T2>() or something like that. Here is the example modified from your code:
public class Bird { }
public class Pegion : Bird { }
public interface IBirdCalculations<in T> {
void SetTField(T value);
}
public class BirdCalculations<T> : IBirdCalculations<T>
{
private T TField;
public void SetTField(T value)
{
this.TField = value;
}
}
class Program
{
static void Main() {
IBirdCalculations<Pegion> bc2 = new BirdCalculations<Bird>(); //Line 1
IBirdCalculations<Bird> bc1 = new BirdCalculations<Bird>();
bc1.SetTField(new Pegion()); //Line 2
}
}
Notice that you cannot assign an instance of BirdCalculations<Pegion> to IBirdCalculations<Bird> reference because if that were possible somebody might invoke something like SetTField(parrot) and that shouldn't be allowed.
PS: Arrays in C# is not a variance, it is somehow historically allowed to be used like that but it actually breaks type-safe system. My best guess is that it was necessary when we had no generic in .NET which is like 15+ years ago.
This isn't doing what you think it is;
IEnumerable<Object> l1 = new List<string>();
// The following line executes just fine.
l1 = l1.Append(33);
First you're assigning a list to l1, as you expect. But then you're calling IEnumerable<>.Append() which is equivalent to;
public static IEnumerable<T> Append<T>(this IEnumerable<T> source, T obj)
{
foreach (var s in source)
yield return s;
yield return obj;
}
In other words, Append create a new IEnumerable that can be used to visit each element of your list, then the value you appended.
Covariance is safe for reading, but not for writing. When using an array, you can set a value in the array to an arbitrary type - this is not type safe, and that's the unwanted type escape. The same way, contravariance is safe for writing, but not for reading. Unfortunately, there were no ways to constrain variance in arrays back when that was implemented, other than making them entirely type invariant - which would severely limit code reuse without generics (just imagine how something like Array.Sort would work).
You cannot change an enumerable. Enumerables are read only. You did not add any item to the enumerable, and you didn't "modify" anything inside that enumerable. What Append does is create a new IEnumerable<object>. There's no type safety violation. To get a mental picture, you can imagine the new enumerable containing the old enumerable - but it doesn't change anything. All of the items that the enumerables might return still satisfy the original constraint - they're all object.
I'm taking my first steps in c # & asp.net and I'm enjoying it much.
Now, I have a question...
Is there a function in C# to call a class/method as in php?
For example:
$class = array(
"foo", // class name
"bar" // method name
);
$params = array(
"one",
"two"
);
call_user_func_array($class, $params); //execute Foo->bar("one","two");
Nope, there is nothing built in to do exactly that. You could build a method that does something similar using reflection, but it seems like a solution looking for a problem.
void Main()
{
CallUserFuncArray("UserQuery+Foo", "Bar", "One", "Two");
}
// Define other methods and classes here
public class Foo
{
public static void Bar(string a, string b){}
}
public void CallUserFuncArray(string className, string methodName, params object[] args)
{
Type.GetType(className).GetMethod(methodName).Invoke(null, args);
}
As others have noted, there are multiple ways to simulate this, but no "baked-in" functionality in C#. The most flexible way is with reflection, but you can do it in a much simpler (and easier to deal with) way if you know the list of methods you'll be calling beforehand.
class Foo
{
public static string FooA(int p1, int p2)
{
return "FooA:" + p1 + p2;
}
public static string FooB(int p1, int p2) { return "FooB:" + p1 + p2; }
public static string FooC(int p1, int p2) { return "FooC:" + p1 + p2; }
}
class Bar
{
//You can use Func<int, int, object> instead of a delegate type,
//but this way is a little easier to read.
public delegate string Del(int p1, int p2);
public static string DoStuff()
{
var classes = new Dictionary<string, Dictionary<string, Del>>();
classes.Add("Foo", new Dictionary<string, Del>());
classes["Foo"].Add("FooA", Foo.FooA);
classes["Foo"].Add("FooB", Foo.FooB);
classes["Foo"].Add("FooC", Foo.FooC);
//...snip...
return classes["Foo"]["FooA"](5, 7);
}
}
Which, by the way, does work.
If you don't know which methods you want to make available this way, I suggest you reconsider whaever you're trying to do. The only reason I can think of for using strings to choose your execution path would be if you were planning to get those strings from the user. Not only is it a huge no-no to expose inner details of your application like this, but it comes dangerously close to eval-type functionality. There's a reason C# doesn't have an eval method, and it isn't because the designers forgot to put it in.
As #StriplingWarrior said, there's no built-in equivalent of call_user_func_array, but you can do something like it with Reflection.
The problem is that Reflection code can get very complicated very quickly, and can be brittle and error-prone if you're not VERY careful.
For example the following function does what you want:
public static void CallUserFuncArray(string[] func, params string[] args)
{
var type = Type.GetType(func[0]);
if (type == null)
{
throw new ArgumentException("The specified Class could not be found");
}
var method = type.GetMethod(func[1], BindingFlags.Static | BindingFlags.Public);
if (method== null)
{
throw new ArgumentException("The specified Method could not be found");
}
method.Invoke(null, args);
}
You call it like this:
var func = new [] { "Foo", "Bar" };
var args = new [] { "one", "two" };
CallUserFuncArray(func, args);
The problems though are many.
The code only works if Bar is a public static method.
There's a whole new layer of complexity if you need to call an instance method on an object.
The code will explode if the parameters in the args array aren't just right for the target method.
There's no support here for calling methods that expect anything other than string parameters. It's possible to query the type of the arguments expected by the method and convert the types before calling 'Invoke', but you're getting even more messy.
There are many more edge cases that blow out the complexity of this code even more if you need to cater for them.
To paraphrase Carl Franklin (of dotNetRocks fame):
I had a problem I needed to solve, so I used Reflection. Now I have two problems.
I you find yourself need to do this sort of thing thenyou probably need to rethink your overall design.
How do I convert
public class MyCustomList: List<MyCustomList>
back to MyCustomList after ordering?
myCustomListObject = myCustomListObject.OrderBy(...);
I tried .ToList() as myCustomListObject which returns null. What should I do?
public class MyCustomList: List<MyCustomList>
{
//stuff you already have here, including your current constructors
public MyCustomList(IEnumerable<MyCustomList> source)
{
//something here that (perhaps after using `this` to call
//one of the existing constructors, loads all of the items
//in source into it. There may be optimisations available
//in particular cases, as a bonus.
}
}
If you really want to be able to do something like the ToList() style, then you can add:
public static class MyBigOClassOHelpfulStaticMethods //maybe pick a better name
{
public static MyCustomList ToMyCustomList(this IEnumerable<MyCustomList> source)
{
return new MyCustomList(source);
}
}
Which isn't far off how ToList() works.
All this said though, if you are going to be often writing over the first MyCustomList with the new one, then there'd be something to gain by calling Sort instead of OrderBy, as Sort will sort the list in-place.
The problem is that ToList() will return a List. You cannot convert it to a MyCustomList just like you cannot convert another object some somthing that it isnt.
List<string> result = myCustomListObject.OrderBy(...).ToList();
If you really need a MyCustomListObject you should create a constructor that accepts a explicit cast operation.
If MyCustomList is just another name for List<string> you could use:
using MyCustomList = List<string>;
Then it will work like you want it to.
The return value of OrderBy simply is no instance of MyCustomList, and neither is the return value of ToList. Therefore, you cannot cast it to MyCustomList.
The only options you have are:
You create a new instance of MyCustomList and add the elements returned by OrderBy.
You replace the current contentes of your MyCustomList instance with the elements returned by OrderBy.
Without knowing more about your MyCustomList class, it is impossible to tell more. As it inherits from List<MyCustomList>, however, it can be assumed that both of the above options are feasible.
I agree with O. R. Mapper in that, without knowing more about MyCustomList, it's hard to answer. But you could just do something simple like this (again, without knowing more, this may now work):
void Main()
{
var list = new MyList() { new Stuff() { ugg = "z" }, new Stuff() { ugg = "b" } };
var myOrderedList = list.OrderBy(s => s.ugg);
myOrderedList.ToList().Dump();
var list2 = new MyList();
list2.AddRange(myOrderedList);
list2.GetType().Name.Dump();
}
public class Stuff{
public string ugg {get;set;}
}
// Define other methods and classes here
public class MyList : List<Stuff>{
}
I use LinqPad to display the contents and type names using the Dump() extension method.
I dont think I understand the point of a delegate method. All the examples I have seen do something like this:
class DelegateClass
{
private List<string> ListString = new List<string>;
delegate void DoSomethingToStringsDelegate(string s);
public base()
{
ListString.Add("string"); ....
}
void ProcessStrings(DoSomethingToStringsDelegate dstsd)
{
foreach(string s in ListString)
dstsd(s);
}
}
class AClass
{
...
void UseDelegateMethod(...)
{
DelegateClass ds = new DelegateClass();
ds.ProcessStrings(new DoSomethingToStringsDelegate(PrintStrings);
}
void PrintStrings(string s)
{
System.out.Write(s);
}
}
I dont understand why this is needed when you could simply just implement a getListStrings() and iterate through the strings yourself, doing what you needed to do, as if it was a delegate.
foreach( string s in ds.ggetListStrings() )
System.out.Write(s);
Private members reason doesnt make sense because I could just do:
global List<Strings> myListStrings = new List<Strings>();
ds.ProcessStrings(new DoSomethingToStringsDelegate(GetStrings);
void GetStrings(string s)
{
myListStrings.Add(s);
}
...and now I have the same list, as a getListStrings() would do ....
Can someone please explain? Thanks so much!
The delegate is useful because it actually acts as a placeholder for any method that takes a string as parameter and returns void.
If you are familiar with C, it is similar to how a function pointer works. In its place you can pass any method that matches the signature and return type.
For example let's say I want to implement a method that sorts a group of objects. In addition to the object list I can also pass a delegate that indicates how the sort is to be done. Since any method matching the delegate can be passed, I can then dynamically switch between different methods if I want for example decreasing or increasing sort:
delegate int comparisonDelegate(int p1, int p2);
void SortArray(int[] array, comparisonDelegate cmp)
{
// determine order according to cmp
}
int CompareDecreasing(int p1, int p2)
{
if(p1 > p2) return -1;
if(p1 < p2) return 1;
return 0;
}
int CompareIncreasing(int p1, int p2)
{
if(p1 > p2) return 1;
if(p1 < p2) return -1;
return 0;
}
Now I can call SortArray as:
SortArray(array, new comparisonDelegate(compareDecreasing));
SortArray(array, new comparisonDelegate(compareIncreasing));
I dont understand why this is needed when you could simply just implement a getListStrings() and iterate through the strings yourself, doing what you needed to do, as if it was a delegate.
The goal here is to make a function that will work on the collection, but do any operation.
This is easier to grasp by example - to see a great example of how and why this is useful, look at LINQ to Objects.
Suppose you want to see how many of your strings are greater than 4 characters - the Enumerable.Count method has an overload that takes a delegate - a Func<T,bool> predicate that can be used. This lets you specify any operation and count the elements, ie:
List<string> listOfStrings = GetListOfStrings();
int countOfStringsGreaterThanFourChars = listOfStrings.Count(s => s.Length > 4);
Here, we're passing a delegate (created via a lambda expression) that gives us our criteria. By having a Count method that takes a delegate, it works for any criteria, so we don't have to reimplement this every time we want a different condition.
Say we want to see how many strings start with "E", we could just use:
int countOfStringsStartingWithE = listOfStrings.Count(s => s.StartsWith("E"));
Again, we only have to write the code that's relevant to our specific need, not duplicate all of the boilerplate code that would be required to loop through our collection and count the items...
Using a delegate in your illustration allows you to change out the implementation of the method.
A better example is that of a Comparer method. I won't get into the IComparer interface, but suffice it to say that, using a delegate, you would be able to modify a sort method's behavior by passing it a delegate to a comparison function.
http://msdn.microsoft.com/en-us/library/system.collections.icomparer.aspx
For one, it allows you to inject different behaviors with the same method signature. In one case you might want to simply add to your list. In another case you might want to add to the list and write to a log file, or whatever else you might want to do in a DoSomethingToStringsDelegate.
Think of it in terms of events. Say you have a class that does some processing on a list of items, and for each item, someone consuming your class may want to be notified that an item has been processed (maybe update a progress bar, or update some other part of the system, whatever). Let's put delegates aside for a second, and let's see how we can implement this using interfaces:
public class MyClassThatDoesSomething
{
private List<string> list = new List<string>();
public void ProcessList()
{
foreach(var item in list)
{
ProcessItem(item);
//how do we notify someone here??
}
}
private void ProcessItem(string item){}
}
Now say someone is consuming this class:
var mc = new MyClassThatDoesSomething();
mc.ProcessList(); //how do I know when each one has been processed?
So solve this problem, let's create an interface:
public interface IItemProcessed
{
void ItemProcessed(string item);
}
We can now refactor our original class:
public class MyClassThatDoesSomething
{
private List<string> list = new List<string>();
public void ProcessList()
{
foreach(var item in list)
{
ProcessItem(item);
//how do we notify someone here??
if(this.Listener != null)
{
this.Listener.ItemProcessed(item);
}
}
}
private void ProcessItem(string item){}
public IItemProcessed Listener {get;set;}
}
and the consumer of your class can now do this:
public class ProcessListener : IItemProcessed
{
public void ItemProcessed(string item)
{
Console.WriteLine(item);
//update progress bar, whatever
}
}
var mc = new MyClassThatDoesSomething();
mc.Listener = new ProcessListener();
mc.ProcessList();
Now that you understand that, you can think of delegates as mini interfaces, and you can then change your original class to this:
public class MyClassThatDoesSomething
{
private List<string> list = new List<string>();
public void ProcessList()
{
foreach(var item in list)
{
ProcessItem(item);
//how do we notify someone here??
if(this.Callback != null)
{
this.Callback(item);
}
}
}
private void ProcessItem(string item){}
public Action<string> Callback {get;set;}
}
and the consumer:
var mc = new MyClassThatDoesSomething();
mc.Listener = s =>
{
Console.WriteLine(s);
//update progress bar, whatever
}
mc.ProcessList();
To summarize, you can think of delegates as a way to provide outsiders a simple "hook" into your code to either let them provide small pieces of logic (think of Linq and filtering a collection) or for callbacks/events like I've demonstrated above.
In c# it's possible to create a list of functions like so:
var myList = new List< Func<Foo> >();
This will allow functions (delegates) that take no arguments and return a value of type Foo to be added to the list. So something like:
Foo myFunc1() { ... }
would be a valid member of that list. My question is, how do I declare the type for a templatized function? How can I construct a List<> that will hold functions of the form:
T myFunc2<T>() { ... }
You need to do that inside a templatized class or method. Then you can refer to the generic type T just as you would refer to the specific type Foo.
In other words:
public class FuncContainer<T>
{
private List<Func<T>> list = new List<Func<T>>();
public void Fill()
{
// Initialize list
}
}
I think the other answers so far have misunderstood the problem... and I don't think you can actually do it, if I've read it correctly. Am I right in saying you'd like to be able to write this:
List<???> list = new List<???>(); // This line won't work
list.Add(Method1);
list.Add(Method2);
...
static int Method1() { ... }
static string Method2() { ... }
If I've misunderstood, and a simple generic type parameter of T in your method or class suffices, I'll delete this answer :)
The closest you could come to the above would be something like this:
public class FuncList
{
private readonly List<Delegate> list = new List<Delegate>();
public void Add<T>(Func<T> func)
{
list.Add(func);
}
}
You'd then use it as:
FuncList list = new FuncList();
list.Add<int>(Method1);
list.Add<string>(Method2);
Quite what you'd do with the list afterwards is tricky... what did you have in mind?
Yes this first signature is completely valid.
The signature of the last function you suggested is the following
List<Func<T>> x;
This holds a list of delegates which take no arguments and produce a T value.