Pages

Thursday, December 30, 2010

Code Snippets Tutorial Part 1

Lambda expression common syntax-CSharp

There are multiple ways of expressing lambdas, depending on the exact scenario - some examples:

// simplest form; no types, no brackets
Func f1 = x => 2 * x;
// optional exlicit argument brackets
Func f2 = (x) => 2 * x;
// optional type specification when used with brackets
Func f3 = (int x) => 2 * x;
// multiple arguments require brackets (types optional)
Func f4 = (x, y) => x * y;
// multiple argument with explicit types
Func f5 = (int x, int y) => x * y;

The signature of the lambda must match the signature of the delegate used (whether it is explicit, like above, or implied by the context in things like .Select(cust => cust.Name)

You can use lambdas without arguments by using an empty expression list:

// no arguments
Func f0 = () => 12;

Ideally, the expression on the right hand side is exactly that; a single expression. The compiler can convert this to either a delegate or an Expression tree:

// expression tree
Expression> f6 = (x, y) => x * y;

However; you can also use statement blocks, but this is then only usable as a delegate:

// braces for a statement body
Func f7 = (x, y) => {
int z = x * y;
Console.WriteLine(z);
return z;
};

Note that even though the .NET 4.0 Expression trees support statement bodies, the C# 4.0 compiler doesn't do this for you, so you are still limited to simple Expression trees unless you do it "the hard way"; see my article on InfoQ for more information.

Calculate relative time

const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;

if (delta < 0)
{
return "not yet";
}
if (delta < 1 * MINUTE)
{
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 2 * MINUTE)
{
return "a minute ago";
}
if (delta < 45 * MINUTE)
{
return ts.Minutes + " minutes ago";
}
if (delta < 90 * MINUTE)
{
return "an hour ago";
}
if (delta < 24 * HOUR)
{
return ts.Hours + " hours ago";
}
if (delta < 48 * HOUR)
{
return "yesterday";
}
if (delta < 30 * DAY)
{
return ts.Days + " days ago";
}
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}


* 2 hours ago
* 3 days ago
* a month ago

Monday, November 1, 2010

Default delegate in C#

Prior to .NET 3.5, it was fairly common to declare your own. Now, Action is a good candidate, but ThreadStart was commonly used (fairly confusingly), or MethodInvoker if you were already referencing winforms.

A quick test (note, running in .NET 4.0, using just some libraries - so not exhaustive):

var qry = from asm in AppDomain.CurrentDomain.GetAssemblies()
from type in asm.GetTypes()
where type.IsSubclassOf(typeof(Delegate))
let method
= type.GetMethod("Invoke")
where method != null && method.ReturnType == typeof(void)
&& method.GetParameters().Length == 0
orderby type.AssemblyQualifiedName
select type.AssemblyQualifiedName;
foreach (var name in qry) Console.WriteLine(name);

shows some more candidates:

System.Action, mscorlib...
System.CrossAppDomainDelegate, mscorlib...
System.IO.Pipes.PipeStreamImpersonationWorker, System.Core...
System.Linq.Expressions.Compiler.LambdaCompiler+WriteBack, System.Core...
System.Net.UnlockConnectionDelegate, System...
System.Runtime.Remoting.Contexts.CrossContextDelegate, mscorlib...
System.Threading.ThreadStart, mscorlib...
System.Windows.Forms.AxHost+AboutBoxDelegate, System.Windows.Forms...
System.Windows.Forms.MethodInvoker, System.Windows.Forms...

Sunday, October 17, 2010

Programmatically create a PDF in my .NET application

using CrystalDecisions.CrystalReports.Engine;

ReportDocument rptCust;
string sDate_time;
string sDestination_path;

CrystalDecisions.Shared.ExportOptions myExportOptions;
CrystalDecisions.Shared.DiskFileDestinationOptions File_destination;
CrystalDecisions.Shared.PdfRtfWordFormatOptions Format_options;

myExportOptions = new CrystalDecisions.Shared.ExportOptions();
File_destination = new CrystalDecisions.Shared.DiskFileDestinationOptions();
Format_options = new CrystalDecisions.Shared.PdfRtfWordFormatOptions();

sDate_time = DateTime.Now.ToString("ddMMyyyyHHmmssff");
sDestination_path = sDestination_file + sPolicy_number + sPolicy_number1 + "-" + sDate_time + ".pdf";

File_destination.DiskFileName = sDestination_path;
myExportOptions = rptCust.ExportOptions;

myExportOptions.ExportDestinationType = CrystalDecisions.Shared.ExportDestinationType.DiskFile;
myExportOptions.ExportFormatType = CrystalDecisions.Shared.ExportFormatType.PortableDocFormat;
myExportOptions.DestinationOptions = File_destination;
myExportOptions.FormatOptions = Format_options;

rptCust.Export();

Convert vb to c sharp project to C# 4.0

1. start a new C# project,
2. add the 4 class files that you have,
3. run them each through the VB->c# translator you linked to originally,
4. dump the VB logging stuff and add in log4net
5. turn the Windows Scripting stuff from VB into C# (I think your problem with this is that the translator above is flipping out on the types of WindowsScripting Host stuff)
6. Compile and test.

With luck, this will take you a couple of hours. With bad luck, it depends on what the project actually does and that will determine how long.

I wish you good luck.

If you decide to go this route, be liberal about commenting out huge parts of code and compiling and working on eliminating compiling errors first. I'll try to keep an eye out to help you with any other specific questions that I see come across the front page.

Saturday, October 16, 2010

Add delegate to interface c#

Those are declaring delegate types. They don't belong in an interface. The events using those delegate types are fine to be in the interface though:

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{
event UpdateStatusEventHandler StatusUpdated;
event StartedEventHandler Started;
}

The implementation won't (and shouldn't) redeclare the delegate type, any more than it would redeclare any other type used in an interface.