C# 4: Generic variance for delegates
Posted by jacekdalkowski in Uncategorized on October 4, 2014
Here are some experiments regarding variance of type parameters for generic delegates in C# 4. There are two kinds of variance: covariance and contravariance. I think of variance as using extended type in place of base type (you could visualise it as a UML diagram, where extended type points to base type). Contravariance is just the opposite: using base type in plase of extended type.
If delgate’s type paramter is variant, it means that we can assign a delegate instance with diffrent type paramter to delegates variable.
Some basic delgates types with variant paramters in C# are Func and Action, simplest of which are:
delegate void Action<in T>(T obj)
, where in T
is contravariant parameter
and
delegate TResult Func<out TResult>()
, where out TResult
is covariant parameter.
It gets pretty funny when it turns out, that in some cases the default variance type can be inverted when delegate type (with variant type paramter) is nested in another delegate type (i.e. when delegate with variant type paramter becomes a parameter for another delegate). Before showing some cases, let’s bring up a terse rule from a great book “C# in depth” by Jon Skeet: “As a quick rule of thumb, you can think of nested contravariance as reversing the previous variance, whereas covariance doesn’t, so whereas Action<Action>
is covariant in T, Action<Action<Action>>
is contravariant. Compare that with Func
variance, where you can write Func<Func<Func<...Func<T>...>>>
with as many levels of nesting as you like and still get covariance”.
For the sake of latter examples, let’s assume that we have a following class hierachy:
Object <- Person <- Child
Let’s start with simple Func
covariance:
Func<object> objectOutputFunc = () => new object(); Func<Person> personOutputFunc = () => new Person(); Func<Child> childOuputFunc = () => new Child(); // delegate expected to return Person can return Child personOutputFunc = childOuputFunc; personOutputFunc = () => new Child(); // won't compile: personOutputFunc = objectOutputFunc; // won't compile: personOutputFunc = () => new object();
And some obvious behavior of Action
covariance:
// an action, which will be fed with object Action<object> actionObject = new Action<object>(o => Console.WriteLine(o)); // an action, which will be fed with Person Action<Person> actionPerson; // an action, which will be fed with Child Action<Child> actionChild; // wont compile (syntax): actionPerson = (Object o) => Console.WriteLine(o); // an action which expects an object can be fed with a person actionPerson = actionObject; //actionPerson(obj); actionPerson(person); actionPerson(child);
As noted earlier, nesting Func inside Func does not change type paramter variance (i.e. T in Func<Func<Func<...Func<T>...>>>
is always contravariant).
Let’s check what happens when we nest Action inside Func:
Func<Action<object>> funcActionObject = () => o => Console.WriteLine(o); Func<Action<Person>> funcActionPerson = () => p => Console.WriteLine(p); Func<Action<Child>> funcActionChild = () => c => Console.WriteLine(c); // action type parameter is contravariant and so it is here funcActionPerson = funcActionObject; Func<Func<Action<object>>> funcFuncActionObject = () => () => o => Console.WriteLine(o); Func<Func<Action<Person>>> funcFuncActionPerson = () => () => p => Console.WriteLine(p); Func<Func<Action<Child>>> funcFuncActionChild = () => () => c => Console.WriteLine(c); // action type parameter is contravariant and so it is here funcFuncActionPerson = funcFuncActionObject;
Func did not change variance o Action parameter, so Jon Skeet’s rule still applies (that should be no surprise).
Now, let’s see how Action changes variance of nested Func:
Action<Func<object>> actionFuncObject = (f) => f.Invoke(); Action<Func<Person>> actionFuncPerson = (f) => f.Invoke(); Action<Func<Child>> actionFuncChild = (f) => f.Invoke (); // won't compile: actionFuncPerson = actionFuncChild; // normally, func is covariant, // but here, type parameter became contravariant actionFuncPerson = actionFuncObject; // won't compile: actionFuncPerson = (Func<object> f) => f.Invoke(); Action<Func<Func<object>>> actionFuncFuncObject = (ffo) => ffo.Invoke().Invoke(); Action<Func<Func<Person>>> actionFuncFuncPerson = (ffp) => ffp.Invoke().Invoke(); Action<Func<Func<Child>>> actionFuncFuncChild = (ffc) => ffc.Invoke().Invoke(); // normally, func is covariant, // but here, type parameter became contravariant actionFuncFuncPerson = actionFuncFuncObject; // won't compile: actionFuncFuncPerson = (Func<Func<object>> ffo) => ffo.Invoke().Invoke();
Indeed, when nesting Func inside Action, variance of type parameter of nested Func changed.
Finally, let’s check how type parameters variance change when nesting sequences of Actions:
// ======== Action<Person> fun ======== // action expects an object to work on. // actual object to work on is supplied in place of action invocation // an action, which will be fed with object Action<object> actionObject = new Action<object>(o => Console.WriteLine(o)); // an action, which will be fed with Person Action<Person> actionPerson; // an action, which will be fed with Child Action<Child> actionChild; // wont compile (syntax): actionPerson = (Object o) => Console.WriteLine(o); // an action which expects an object can be fed with a person actionPerson = actionObject; //actionPerson(obj); actionPerson(person); actionPerson(child); // ======== Action<Action<Person>> fun ======== // action expects another action which will be suplied with the object by the first action. // actual object to work on is supplied in place of action definition // an action, which will be fed with an action for object Action<Action<object>> actionActionObject; // an action, which will be fed with an action for person Action<Action<Person>> actionActionPerson; // an action, which will be fed with an action for child Action<Action<Child>> actionActionChild = new Action<Action<Child>>(a => a.Invoke (child)); // an action, which expects an action to which it may pass a child, // can be fed with an action which expects a person actionActionPerson = actionActionChild; actionActionPerson(new Action<object>(o => Console.WriteLine("Object: " + o))); actionActionPerson(p => Console.WriteLine("Person name: " + p.Name)); //actionActionPerson(new Action<Child>(c => Console.WriteLine("Child toys: " + c.NumberOfToys))); actionActionChild(new Action<Child>(c => Console.WriteLine("Child toys: " + c.NumberOfToys))); // ======== ActionAction<<Action<Person>>> fun ======== // action (1) expects another action (2), which will be suplied with another action (from action 1) // and that another action will work on parameter supplied "within" action (1). // actual object to work on can be supplied in place of action invocation (simplest case). Action<Action<Action<object>>> actionActionActionObject = a => a.Invoke(o => Console.WriteLine("Tripple action: " + o)); Action<Action<Action<Person>>> actionActionActionPerson; Action<Action<Action<Child>>> actionActionActionChild; actionActionActionObject(ao => ao.Invoke(obj)); actionActionActionPerson = actionActionActionObject; actionActionActionPerson(ap => ap.Invoke(person)); // ======== ActionActionAction<<Action<Person>>> fun ======== Action<Action<Action<Action<object>>>> actionActionActionActionObject; Action<Action<Action<Action<Person>>>> actionActionActionActionPerson; Action<Action<Action<Action<Child>>>> actionActionActionActionChild = a => a.Invoke(a2 => a2.Invoke(child)); actionActionActionActionChild(a => a.Invoke(c => Console.WriteLine("Quadruple action: Child toys: " + c.NumberOfToys))); //actionActionActionPerson = actionActionActionActionChild; //actionActionActionPerson(ap => ap.Invoke(person));
Hope you had fun!
WinDbg SOS cheatsheet
Posted by jacekdalkowski in Uncategorized on December 26, 2013
SOS (Son of Strike) WinDbg extensions allows you to debug (and monitor resource usage, find leaks, help spot deadlocks) .NET applications. Here are some useful SOS commands which may be executed in WinDbg or Visual Studio’s immediate window. All SOS command can be found here: https://msdn.microsoft.com/en-us/library/bb190764(v=vs.110).aspx
.loadby sos clr
loads SOS extension
.cls
clears the screen
Memory stuff:
!eeheap -gc
information about managed heap
!dumpheap -stat
lists loaded classes, number of instances of each class and addres of Method Table (MT)
!dumpheap -mt [MT]
dumps objects of given class (i.e. of class which has method table at address)
!do [object's address]
dumps particular managed object
du [object's address]
dumps particular not-necessarily managed object
!gcroot [object's address]
shows reference chain to given object
Stack stuff:
~* e !clrstack
for every (*) thread (~) execute (e) command !clrstack (which prints current stack)
!syncblock
lists synchronization blocks owned by active threads (.i.e you may check if some thread is being blocked)
~30s
prints information about thread 30 and sets current “debugging context” to thread 30, so then one can call
!clrstack
to print stack for previously set thread
!threadpool
threadpool info
!threads
~* kb
prints native stack for all threads
iOS and OS X: Utility class for accessing NSManagedObjectModel and NSManagedObjectContext
Posted by jacekdalkowski in Uncategorized on August 17, 2013
Some projects templates by XCode wizards provide code for accessing NSManagedObjectModel and NSManagedObjectContext, but some other do not. In case of projects which were not provided with auto-generated code for accessing model data, here is a class (based on these auto-genereted stuff) which accesses NSManagedObjectModel and NSManagedObjectContext. For the code to work properly, values for field “objectModelFileName” and “bundleIndentifier” have to be provided. For example, if name of file with model data is “MyApp.xcdatamodelId”, then “objectModelFileName” should have value “MyApp” and “bundleIndentifier” should have value which is equal to name of the application’s bundle name.
Header:
#import <Cocoa/Cocoa.h> @interface ManagedObjectContextProvider : NSObject @property (retain, nonatomic) NSString *objectModelFileName; @property (retain, nonatomic) NSString *bundleIndentifier; @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; @end
Class definition:
#import "ManagedObjectContextProvider.h" @implementation ManagedObjectContextProvider @synthesize objectModelFileName = __objectModelFileName; @synthesize bundleIndentifier = __bundleIndentifier; @synthesize persistentStoreCoordinator = __persistentStoreCoordinator; @synthesize managedObjectModel = __managedObjectModel; @synthesize managedObjectContext = __managedObjectContext; // Returns the directory the application uses to store the Core Data store file. - (NSURL *)applicationFilesDirectory { NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject]; return [appSupportURL URLByAppendingPathComponent:__bundleIndentifier]; } // Creates if necessary and returns the managed object model for the application. - (NSManagedObjectModel *)managedObjectModel { if (__managedObjectModel) { return __managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:__objectModelFileName withExtension:@"momd"]; __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return __managedObjectModel; } // Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.) - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (__persistentStoreCoordinator) { return __persistentStoreCoordinator; } NSManagedObjectModel *mom = [self managedObjectModel]; if (!mom) { NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd)); return nil; } NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *applicationFilesDirectory = [self applicationFilesDirectory]; NSError *error = nil; NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:[NSArray arrayWithObject:NSURLIsDirectoryKey] error:&error]; if (!properties) { BOOL ok = NO; if ([error code] == NSFileReadNoSuchFileError) { ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error]; } if (!ok) { [[NSApplication sharedApplication] presentError:error]; return nil; } } else { if (![[properties objectForKey:NSURLIsDirectoryKey] boolValue]) { // Customize and localize this error. NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]]; NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setValue:failureDescription forKey:NSLocalizedDescriptionKey]; error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict]; [[NSApplication sharedApplication] presentError:error]; return nil; } } NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"CocoaApp1.storedata"]; NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom]; if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) { [[NSApplication sharedApplication] presentError:error]; return nil; } __persistentStoreCoordinator = coordinator; return __persistentStoreCoordinator; } // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) - (NSManagedObjectContext *)managedObjectContext { if (__managedObjectContext) { return __managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (!coordinator) { NSMutableDictionary *dict = [NSMutableDictionary dictionary]; [dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey]; [dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey]; NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; [[NSApplication sharedApplication] presentError:error]; return nil; } __managedObjectContext = [[NSManagedObjectContext alloc] init]; [__managedObjectContext setPersistentStoreCoordinator:coordinator]; return __managedObjectContext; } @end
Simple configuration file for a .NET application
Posted by jacekdalkowski in Uncategorized on August 11, 2013
In order to read simple “key-value” configuration file for a .NET application, a class shown below may be used:
using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace SomeNamespace { public class SimpleConfigurationManager { public static string GetConfigurationParameterValue(string key) { Configuration config = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location); try { AppSettingsSection c = (AppSettingsSection)config.GetSection("some_section_in_config_file"); var i = c.ElementInformation; return c.Settings[key].Value; } catch (Exception e) { return null; } } } }
The config file, which will be read by the class:
- should be stored in the same directory as the executable file
- should be named according to this pattern: executable file name + “.config”, for example: MyApp.exe.config
- should have following structure:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="some_section_in_config_file" type="System.Configuration.AppSettingsSection" /> </configSections> <some_section_in_config_file> <add key="some_key_1" value="1024" /> <add key="some_key_2" value="www.google.com" /> <add key="and_some_other_key" value="true" /> </some_section_in_config_file> </configuration>
Voodoo doll 3D for iOS and Android
Posted by jacekdalkowski in Computer science, Projects on April 14, 2012
I have just finished a Voodoo Doll game. The game simulates a rag doll – you can drag it, burn it with a candle flame, stick with pins and nail to the table. The game was made in Unity3D.
You can download and have fun with the game: Android version.
Count number of occurrences of distinct values using LINQ
Posted by jacekdalkowski in Code samples, Computer science on March 22, 2012
C# code snippet below finds distinct (case-insensitive) strings in a collection and counts number of occurrences of each unique (case-insensitive again) one.
static void Main(string[] args) { string[] sa = { "ala", "ma", "ala", "ma", "ma", "abc" }; var res = from uniqueString in sa.Distinct(StringComparer.CurrentCultureIgnoreCase).ToList() select new { str = uniqueString, occur = sa.Count(s => s.ToLower().Equals(uniqueString.ToLower())) }; foreach(var el in res){ Console.Write(el.GetType().GetProperty("str").GetValue(el, null) + "\t"); Console.WriteLine(el.GetType().GetProperty("occur").GetValue(el, null)); } Console.ReadLine(); }
Blender: Script for exporting models to xml
Posted by jacekdalkowski in Code samples, Computer science on February 26, 2012
Python script shown below exports models from Blender 2.44 (but it should work with other versions too) to XML file. the structure of output XML file is something like this:
<objects> <object name="Cube"> <vertices count="18"> <v> <c> <x>-0.164879</x><y>0.242091</y><z>-5.895331</z> </c> <n> <x>0.577349</x><y>0.577349</y><z>-0.577349</z> </n> </v> <v> <c> <x>-0.164879</x><y>-0.524807</y><z>-5.895331</z> </c> <n> <x>0.577349</x><y>-0.577349</y><z>-0.577349</z> </n> </v>
The script itself is shown below. It can be easily modified in order to produce files of some other structure.
#!BPY """ Name: 'To-XML model exporter' Blender: 244 Group: 'Export' Tooltip: 'My to-XML model exporter' """ import Blender from Blender import Window import bpy print "\n ======== To-XML model exporter ======== " # just in case - leave edit mode if Window.EditMode(): print "Forcing to leave edit mode" Window.EditMode(0) # create XML structure xmlString = "<objects>" # for each object in the scene for ob in bpy.data.scenes.active.objects: # if this is a mesh if ob.type == "Mesh": xmlString += "\n\t<object name=\"" + ob.name + "\">" mesh = ob.getData(mesh=1) xmlString += "\n\t\t<vertices count=\"" + ("%d" % (len(mesh.faces) * 3)) + "\">" allFacesWithNoUV = True allFacesWithUV = True # write down vericles in order how they should be rendered by opengl # i.e. if a particualr vertex appears in multiple faces, the vertes is written down multiple times for face in mesh.faces: for i in range(0, len(face.v)): vertInFace = face.v[i] xmlString += "\n\t\t\t<v>" # write vertilce coords xmlString += "\n\t\t\t\t<c>" xmlString += "\n\t\t\t\t\t<x>" + ("%f" % mesh.verts[vertInFace.index].co.x) + "</x><y>" + ("%f" % mesh.verts[vertInFace.index].co.y) +"</y><z>" + ("%f" % mesh.verts[vertInFace.index].co.z) + "</z>" xmlString += "\n\t\t\t\t</c>" # write normals xmlString += "\n\t\t\t\t<n>" xmlString += "\n\t\t\t\t\t<x>" + ("%f" % mesh.verts[vertInFace.index].no.x) + "</x><y>" + ("%f" % mesh.verts[vertInFace.index].no.y) +"</y><z>" + ("%f" % mesh.verts[vertInFace.index].no.z) + "</z>" xmlString += "\n\t\t\t\t</n>" # write texture coords if any if hasattr(face, "uv"): allFacesWithNoUV &= False # there is a face with uv xmlString += "\n\t\t\t\t<uv>" xmlString += "\n\t\t\t\t\t<x>" + ("%f" % face.uv[i].x) + "</x><y>" + ("%f" % ( 1.0 - face.uv[i].y)) +"</y>" xmlString += "\n\t\t\t\t</uv>" else: allFacesWithUV &= False # there is a face with no uv xmlString += "\n\t\t\t</v>" if not allFacesWithUV and not allFacesWithNoUV: print "some faces in object " + ob.name + " are missing uv" if not allFacesWithUV: print "all faces in object " + ob.name + " are missing uv" xmlString += "\n\t\t</vertices>" xmlString += "\n\t</object>" xmlString += "\n</objects>" def write(filename): outputFile = open(filename, "w") outputFile.write(xmlString); outputFile.close() Blender.Window.FileSelector(write, "Export") print "\n ======== end of work ======== "
Android: draw a number of bitmaps or drawables into a single drawable
Posted by jacekdalkowski in Code samples on January 30, 2012
In some cases, you might need to render a numer of bitmaps or drawables into a single drawable. For instance, swapping LayerDrawables of different sizes displayed on top of MapView, might render not as it is supposed to. Code snippet below shows how to render LayerDrawable into a single BitmapDrawable. It is a simplified piece of code and contains “magic numbers”, but anyway, this should show the idea:
public Drawable getPersonMapItemDrawable(Drawable drawable1, Drawable drawable2){ Drawable[] layers = new Drawable[2]; layers[0] = drawable1; layers[1] = drawable2; int resourceBitmapHeight = 136, resourceBitmapWidth = 153; float widthInInches = 0.9f; int widthInPixels = (int)(widthInInches * context.getResources().getDisplayMetrics().densityDpi); int heightInPixels = (int)(widthInPixels * resourceBitmapHeight / resourceBitmapWidth); int insetLeft = 10, insetTop = 10, insetRight = 10, insetBottom = 10; LayerDrawable layerDrawable = new LayerDrawable(layers); layerDrawable.setLayerInset(1, insetLeft, insetTop, insetRight, insetBottom); Bitmap bitmap = Bitmap.createBitmap(widthInPixels, heightInPixels, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); layerDrawable.setBounds(0, 0, widthInPixels, heightInPixels); layerDrawable.draw(canvas); BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), bitmap); bitmapDrawable.setBounds(0, 0, widthInPixels, heightInPixels); return bitmapDrawable; }
Augmented Reality
Posted by jacekdalkowski in Computer science, Projects on October 19, 2011
A program created as an assignment project for human-computer interaction at the University.
A webcam captures the view, finds the marker, then the object is drawn at the proper position.
Written in C#, VC++ and C++, using WPF, OpenGl, DIBs and some math.
Not downloadable as the proper marker is needed to play. A movie embeded below created as a part of the task.
Network checkers
Posted by jacekdalkowski in Computer science, Projects on October 19, 2011
A game created as an assignment for Computer Networks. Multithreaded server written in C and running under Linux, client programmed in Java using for instance Java3d, Swing…