Archive for category Uncategorized

C# 4: Generic variance for delegates

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!

Leave a comment

WinDbg SOS cheatsheet

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

Leave a comment

iOS and OS X: Utility class for accessing NSManagedObjectModel and NSManagedObjectContext

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

Leave a comment

Simple configuration file for a .NET application

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:

  1. should be stored in the same directory as the executable file
  2. should be named according to this pattern: executable file name + “.config”, for example: MyApp.exe.config
  3. 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>

Leave a comment