In .Net generics gives a nice way to make type agnostic code that are not limited to a specific type.
The following two types are taken from the plain framework.
interface IBusinessEntity<T>{
T Id {get;set;}
}
interface IDao<T,TT> where T : IBusinessEntity<TT>{
T Get(TT);
TT Save(T);
}
As shown you can use gemeric types as generic parameters for other types. In the IDao interface, I have specified that T must be a IBusinessEntity interface with the TT type as a generic parameter.
In my example I will create a Article class that implements the IBusinessEntity interface and a generic Dao implementation
class Article : IBusinessEntity<int>{
//some code
}
class Dao<T,TT> : IDao<T,TT>{
//some code
}
Now I want to get a dao for the class you just created. As Article has int as a generic parameter, the Dao objects has to defined with the article type as well as int to be able to compile.
var dao = new Dao<Article,int>();
Once you apply "Article", the only valid type as TT is "int". If you apply anything else, the compiler will let you know that "Article" is not valid. The reason for this is that in the definition of IDao, T has a requirement for T, not TT.
It has been bugging me that the compiler complains about the type of T and not the type of TT. T is the important generic parameter, and TT could just be derived from that.
In future releases of .net I would like to be able to write the following.
interface IDao<T<TT>> where T : IBusinessEntity<TT>{
T Get(TT);
TT Save(T);
}
This way I could specify TT as part of the signature, but as TT is derived from what type T is, I would only have to specify T when using it.
When creating the dao I could then write.
var dao = new Dao<Article>();
This is a small improvement, but it would remove some strange dependency error when using multiple generic parameters.
Promoting common sense.
Alternatively: Promoting uncommon sense and exposing common nonsense
Showing posts with label generics. Show all posts
Showing posts with label generics. Show all posts
Wednesday, January 04, 2012
Monday, December 07, 2009
Easy loops
Loops are common in a lot of code. I made a few contructs in plain to make it even easier to do simple iterations in .net.
I know this is sort of thing is common in languages like Ruby or F# but that's not gonna stop me from doing it in C# :)
//do something 3 times 3.Times().Do(i=>Console.WriteLine("Sometext")); //count an integer from 3 to 8 (both included) and do some action for each value. 3.To(8).Do(i=>Console.WriteLine("The number is: " + i ))
I know this is sort of thing is common in languages like Ruby or F# but that's not gonna stop me from doing it in C# :)
The implementation can be found at http://code.google.com/p/plain
Saturday, March 14, 2009
Working on collections and searching for objects
I am reading a book about F# which is a functional language for .net. At the same time I have been introduced to JQuery which is a javascript framework for querying and manipulating objects on a html page. It has sprung some ideas for the plain framework.
What I'm striving for is the possibility to query an object structure for objects. When the objects are returned, it should be possible to perform actions on all these objects in one statement. LINQ might be usefull for querying but at the moment I'm guessing that it won't fulfill my needs.
Lets me give an example of what is currently in progress. This will find all TextBox objects that contain the value '0' and set the background colour on it:
The .find method is an extension method on object, which means you can use it for any object. The .Do method is an extension method to all IEnumerable<> that lets you perform the lambda function on all instances contained in the list.
Another example is by using the Map method.
This will produce a list of strings with that name and value of all textboxes somewhere on the form. The Map method is currently not an extension method as I haven't figured out how to implement the syntax of just just providing one generic parameter to an extension method working on a generic type :(
Actually there is a Map extension method, but it requires you to provide the generic type of the collection as well. In this case it would be .Map<textbox,string>(...)
The one thing that is missing is the syntax to search for objects. Will it be LINQ or will it be a homegrown dsl?
If you want to use the .Do method here it is:
otherwise you can wait for it to apear in the plain framework :)
What I'm striving for is the possibility to query an object structure for objects. When the objects are returned, it should be possible to perform actions on all these objects in one statement. LINQ might be usefull for querying but at the moment I'm guessing that it won't fulfill my needs.
Lets me give an example of what is currently in progress. This will find all TextBox objects that contain the value '0' and set the background colour on it:
form.find<textbox>("[.Text='0']").Do(t=>t.BackColor= Color.Azure);
The .find method is an extension method on object, which means you can use it for any object. The .Do method is an extension method to all IEnumerable<> that lets you perform the lambda function on all instances contained in the list.
Another example is by using the Map method.
IList<string> textboxValues = form.find<textbox>().Map<string>(t=>x.Name +": " + x.Text);
This will produce a list of strings with that name and value of all textboxes somewhere on the form. The Map method is currently not an extension method as I haven't figured out how to implement the syntax of just just providing one generic parameter to an extension method working on a generic type :(
Actually there is a Map extension method, but it requires you to provide the generic type of the collection as well. In this case it would be .Map<textbox,string>(...)
The one thing that is missing is the syntax to search for objects. Will it be LINQ or will it be a homegrown dsl?
If you want to use the .Do method here it is:
public delegate void OneParemeterNoReturn(T x);
public static void Do<t>(this IEnumerable<t> o,OneParemeterNoReturn<t> func){
foreach(T t in o){
func.Invoke(t);
}
}
otherwise you can wait for it to apear in the plain framework :)
Tuesday, February 10, 2009
Creating overloaded methods with extension methods
I have an interface in an application.
I want the interface to be simple to implement so it basically contains one method that has a number of parameters.
I want the interface to be simple to use, so I have implemented a number of extension methods that will work as overloads for the method specified in the interface.
So far so good. My next wish is to make the interface generic. This is where the everything falls apart. Apparently you are not able to make extension methods on a generic type. Every time i come across such mismatch between part of the .Net framework I am very sad. I wish the next version could just be a little coherent. :(
I want the interface to be simple to implement so it basically contains one method that has a number of parameters.
I want the interface to be simple to use, so I have implemented a number of extension methods that will work as overloads for the method specified in the interface.
So far so good. My next wish is to make the interface generic. This is where the everything falls apart. Apparently you are not able to make extension methods on a generic type. Every time i come across such mismatch between part of the .Net framework I am very sad. I wish the next version could just be a little coherent. :(
Etiketter:
.Net,
3.5,
Extension methods,
generics
Sunday, October 21, 2007
Consuming generic types as a generic parameter
What is he talking about? Well, I have a hard time expressing myself when it comes to generics. I'm trying to make a library I can use across projects
This is what I want to do:
That way I can let my domain objects implement the BusinessEntity interface and they can be consumed by my EntityList. In the following I have a domain class called Document.
To me this all makes sense. Sadly it doesn't compile :( The problem is that TT in the EntityList is not defined. As far as I know I have to define both T and TT on EntityList even though TT is given once I have defined T. Now it loks like this:
I'm not to happy about the extra generic parameter on the EntityList. Once T is defined, there can be only one valid type of TT. But because of the way you have to define it, the compiler will not complain about the TT, but actually about the fact that T doesn't implement BusinessEntity<TT>. This means that if TT is defined as string for instance, the error message from the compiler will be: Error, Document does not implement the interface BusinessEntity<string>. This will make no sense to the programmer trying to use the class.
If you have any solution to this, please let me know :)
This is what I want to do:
interface BusinessEntity<T>{...}
class EntityList<T> where T : BusinessEntity<TT>{...}
That way I can let my domain objects implement the BusinessEntity interface and they can be consumed by my EntityList. In the following I have a domain class called Document.
//defining Document
class Document : BusinessEntity<int>{...}
//creating instance
EntityList<Document> list = new EntityList<Document>();
To me this all makes sense. Sadly it doesn't compile :( The problem is that TT in the EntityList is not defined. As far as I know I have to define both T and TT on EntityList even though TT is given once I have defined T. Now it loks like this:
//definition
class EntityList<T,TT> where T : BusinessEntity<TT>{...}
//creating instance
EntityList<Document,int> list = new EntityList<Document,int>();
I'm not to happy about the extra generic parameter on the EntityList. Once T is defined, there can be only one valid type of TT. But because of the way you have to define it, the compiler will not complain about the TT, but actually about the fact that T doesn't implement BusinessEntity<TT>. This means that if TT is defined as string for instance, the error message from the compiler will be: Error, Document does not implement the interface BusinessEntity<string>. This will make no sense to the programmer trying to use the class.
If you have any solution to this, please let me know :)
Etiketter:
.Net,
components,
generics
Subscribe to:
Posts (Atom)