I have some code at my job that uses ASP.net (which I have never touched) but I need to sort it. Here is the ListBox that I need to sort by Dscrp:
foreach (InteractiveInfo template in ddlsource)
{
Product thisProduct = FindProduct(template.UProductId);
if (thisProduct != null)
{
ddlProducts.Items.Add(
new ListItem(
string.Format("{0} ({1})", thisProduct.Dscrp, thisProduct.UProductId),
template.UProductId.ToString(CultureInfo.InvariantCulture)));
}
}
ddlProducts.DataBind();
}
I found this link:
https://gist.github.com/chartek/1655779
so I tried adding this at the end:
ddlProducts.Items.Sort();
but it just gives me this error:
Does not contain a definition for 'Sort'
If your application is on .NET 3.5 or above, take a look at MSDN: Extension Methods.
The tutorial link you provided is making use of the extension method concept where Sort() method is decorated onto ListItemCollection (i.e. ddlProducts.Items) type.
The extension methods should be defined inside non-generic static class. So the tutorial missing a class definition. You can try with:
public static class ExtensionsMethods //Notice the static class
{
public static void Sort(this ListItemCollection items)
{
//... Implement rest of logic from the tutorial
}
// Other extension methods, if required.
}
Hope this help you.
Use something like this its not perfect but update it as per your requirement
public static void Sort(this ListItemCollection items)
{
var itemsArray = new ListItem[items.Count];
items.CopyTo(itemsArray,0);
Array.Sort(itemsArray, (x, y) => (string.Compare(x.Value, y.Value, StringComparison.Ordinal)));
items.Clear();
items.AddRange(itemsArray);
}
Related
This question already has answers here:
Adding new method to List<T> over object from which is made of
(3 answers)
Closed 1 year ago.
I know this is a bit odd and I do know another way to work around this but I was wonder if it is possible to have a method that would affect a list of itself. I'll explain.
This would be my workaround
public class Example
{
public void Sanitize()
{
// Does logic sanitize itself using API
}
public static List<Example> Sanitize(List<Example> examples)
{
/// returns a list of sanitized Examples
}
}
How the Example would be able to work on its own.
// Base Example sanitized
Example example = new Example(...);
example.Sanitize();
What I would also like to do
// Whole list sanitized
List<Example> examples = new List<Example> {...};
examples.Sanitize();
Is there a way to do that instead of being required to do this?
List<Example> startingExamples = new List<Example> { ... }
List<Example> endingExamples = Example.Sanitize(startingExamples);
You can have your static method iterate and mutate the list elements in place.
public class Example
{
public void Sanitize()
{
// Does logic sanitize itself using API
}
public static void Sanitize(List<Example> examples)
{
foreach (var example in examples)
{
example.Sanitize();
}
}
}
Note that you cannot modify the list itself while iterating it, but you can make changes to the elements of the list.
Looks like you could use an extension method.
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type. For client code written in C#, F# and Visual Basic, there's no apparent difference between calling an extension method and the methods defined in a type.
An extension method is a static method on a static class that is visible to the code that is using it. For example, public code. The first parameter of the method is the type that the method operates on and must be preceded with the this modifier.
So, for example, you could do something like this...
public static class EnumerableOfExampleExtensions
{
public static void Sanitize(this IEnumerable<Example> examples) /*or List is fine*/
{
// Null checks on examples...
foreach (var example in examples)
{
example.Sanitize();
}
}
}
Then you can call it as an instance method on any IEnumerable<Example>.
List<Example> examples = new List<Example>();
examples.Sanitize();
You can use an extension method to add functionality to the list.
static class ExtensionMethods
{
public static void Sanitize(this List<Example> source)
{
foreach (var item in source) item.Sanitize();
}
}
Now you can do this:
var list = new List<Example>();
list.Sanitize();
Edit: The collective "Hey stupid" was a very nice reminder to re-think my original problem. My curiosity still stands on the subject so I've edited out the bad idea bits.
Given an extension method:
public static class Util {
public static string Triple<T>(this T t) {
var builder = new StringBuilder();
foreach (char c in t.ToString()) {
builder.Append(c, 3);
}
return builder.ToString();
}
}
I know I can call this method using either the instance member syntax,i.e. foo.Triple(), or with static method syntax, Util.Triple(foo). Do I have a way to make the extension method aware of in which manner it is called? Consider (not valid C#):
public static class Util {
public static string Triple<T>(this T t) {
if (calledStatic) {
// do something if called by static syntax
} else {
// do something if not called by static syntax
}
var builder = new StringBuilder();
foreach (char c in t.ToString()) {
builder.Append(c, 3);
}
return builder.ToString();
}
}
I've checked the C# language specification, specifically regarding extension methods, SO questions, and am at a loss.
Bottom line version: Can I make an extension method aware of the manner in which it is called?
No. You can't. Compiler changes your extension method instance-like call to static method call anyway.
That's not possible. Extension methods are just "compiler magic", the compiled version of foo.Triple() will look like Util.Triple(foo) anyway.
Consider the following method example:
public static string[] ParseOptions()
{
return Environment.GetCommandLineArgs();
}
What would I have to do to create an extension that would make ParseOptions() return all command line arguments in lower case?
I would like to be able to use the extension as follows:
var argArray = ParseOptions().MyExtToLower();
Note: I'm asking this to better understand how to create an extension for a method. I'm not actually interested in getting lower case command line arguments this way.
public static string[] MyExtToLower(this string[] source)
{
for (int i = 0; i < source.Length; i++)
{
source[i] = source[i].ToLower();
}
return source;
}
Notice the this keyword in the parameter list. That is what makes it possible to call the method like this:
var argArray = ParseOptions().MyExtToLower();
To be clear, you're not actually adding an extension to a method here. What you are doing is adding an extension to the type that the method returns.
You seem to be talking about Fluent Interfaces. Look at this example - http://blog.raffaeu.com/archive/2010/06/26/how-to-write-fluent-interface-with-c-and-lambda.aspx
Or, you can create extension methods on the type you are returning ( in your case, string[] ) to get the method chaining - http://msdn.microsoft.com/en-us/library/bb383977.aspx
For the syntax you describe you would have to extend String[] or possibly IEnumerable<String> the following way:
public static class MyExtensions {
public static String[] MyExtToLower(this String[] strings) {
return strings.Select(s => s.toLower()).ToArray();
}
public static IEnumerable<String> MyExtToLower(this IEnumerable<String> strings) {
return strings.Select(s => s.toLower());
}
}
You don't create extension of methods, you create methods which extend objects' capabilities. Those methods must be static and part of a static class. They must have one parameter marked with the this keyword to indicate which object you want to extend. In your case, you must write something like:
// the class must be static, I usually declare a class reserved for extension method.
// I mark it as partial so that I can put every method in the same file where I use it.
public static partial class Extension {
// This is the extension method; it must be static. Note the 'this' keyword before
// the first parameter: it tells the compiler extends the string[] type.
public static MyExtToLower( this string[ ] args ) {
// your code
}
}
Note that you cannot override instance method. Altough you can have a method with the same signature as an instance method that method will be never called due to the way the compiler binds to.
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.
I've got a base class:
public abstract class StuffBase
{
public abstract void DoSomething();
}
And two derived classes
public class Stuff1 : StuffBase
{
public void DoSomething()
{
Console.WriteLine("Stuff 1 did something cool!");
}
public Stuff1()
{
Console.WriteLine("New stuff 1 reporting for duty!");
}
}
public class Stuff2 : StuffBase
{
public void DoSomething()
{
Console.WriteLine("Stuff 2 did something cool!");
}
public Stuff1()
{
Console.WriteLine("New stuff 2 reporting for duty!");
}
}
Okay, now say I've got a list of items:
var items = new List<StuffBase>();
items.Add(new Stuff1());
items.Add(new Stuff2());
and I want them all to call their DoSomething() method. I could expect to just iterate the list and call their DoSomething() method, so let's say I've got a method to do that called AllDoSomething() that just iterates over the list and does the job:
public static void AllDoSomething(List<StuffBase> items)
{
items.ForEach(i => i.DoSomething());
}
What is the practical difference of the following method?
public static void AllDoSomething<T>(List<T> items) where T: StuffBase
{
items.ForEach(i => i.DoSomething());
}
Both methods appear in real terms, although being syntactically different, to be doing the same thing.
Are they just different ways of doing the same thing? I understand generics and type constraints but can't see why I would use one way over the other in this instance.
This is because as of yet, C# does not support Covariance.
More formally, in C# v2.0 if T is a
subtype of U, then T[] is a subtype of
U[], but G is not a subtype of G
(where G is any generic type). In
type-theory terminology, we describe
this behavior by saying that C# array
types are “covariant” and generic
types are “invariant”.
Reference: http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx
If you have the following method :
public static void AllDoSomething(List<StuffBase> items)
{
items.ForEach(i => i.DoSomething());
}
var items = new List<Stuff2>();
x.AllDoSomething(items); //Does not compile
Where as if you use the generic type constraint, it will.
For more information about Covariance and Contravariance], check out Eric Lippert's series of posts.
Other posts worth reading :
http://www.pabich.eu/blog/archive/2008/02/12/c-generics---parameter-variance-its-constraints-and-how-it.aspx
http://blogs.msdn.com/rmbyers/archive/2006/06/01/613690.aspx
http://msdn.microsoft.com/en-us/library/ms228359(VS.80).aspx
http://www.csharp411.com/convert-between-generic-ienumerablet/
http://research.microsoft.com/apps/pubs/default.aspx?id=64042
Why can't List<parent> = List<child>?
Suppose you had a list:
List<Stuff1> l = // get from somewhere
Now try:
AllDoSomething(l);
With the generic version, it will be allowed. With the non-generic, it won't. That's the essential difference. A list of Stuff1 is not a list of StuffBase. But in the generic case, you don't require it to be exactly a list of StuffBase, so it's more flexible.
You could work around that by first copying your list of Stuff1 into a list of StuffBase, to make it compatible with the non-generic version. But then suppose you had a method:
List<T> TransformList<T>(List<T> input) where T : StuffBase
{
List<T> output = new List<T>();
foreach (T item in input)
{
// examine item and decide whether to discard it,
// make new items, whatever
}
return output;
}
Without generics, you could accept a list of StuffBase, but you would then have to return a list of StuffBase. The caller would have to use casts if they knew that the items were really of a derived type. So generics allow you to preserve the actual type of an argument and channel it through the method to the return type.
In the example you provided there is no difference but try the following:
List<Stuff1> items = new List<Stuff1>();
items.Add(new Stuff1());
AllDoSomething(items);
AllDoSomething<StuffBase>(items);
The first call works well but the second one does not compile because of generic covariance