mygrid.setCellExcellType(100000, 2, "ro");
mygrid.setItemImage(100000, "blank.gif");
rowId = 100000
column index = 2
ro = read-only
Friday, August 31, 2012
Friday, August 24, 2012
CI Build File and Web Application Deployment
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0"
DefaultTargets="Compile">
<UsingTask AssemblyFile="C:\svn\project\src\packages\ThirdParty\MSBuildCommunityTasks\AsyncExec.dll" TaskName="AsyncExec.AsyncExec"/>
<UsingTask AssemblyFile="C:\svn\project\src\packages\ThirdParty\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" TaskName="MSBuild.Community.Tasks.XmlRead" />
<ItemGroup>
<SolutionRoot Include="."/>
<BuildArtifacts Include=".\buildartifacts\"/>
<SolutionFile Include="..\src\Project.sln"/>
<MsDeploy Include="..\src\packages\MSdeploy2\msdeploy.exe"/>
<PackageFile Include=".\buildartifacts\package\Project.zip"/>
<Website Include=".\buildartifacts\_PublishedWebsites\Project.Website"/>
</ItemGroup>
<Target Name="Clean">
<RemoveDir Directories="@(BuildArtifacts)"/>
</Target>
<Target Name="Init" DependsOnTargets="Clean">
<MakeDir Directories="@(BuildArtifacts)"/>
</Target>
<Target Name="Compile" DependsOnTargets="Init">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
</PropertyGroup>
<MSBuild Projects="@(SolutionFile)" Properties="OutDir=%(BuildArtifacts.FullPath);
Configuration=$(Configuration)"/>
</Target>
<Target Name="Package" DependsOnTargets="Compile">
<PropertyGroup>
<PackageDir>%(PackageFile.RootDir)%(PackageFile.Directory)</PackageDir>
<Source>%(Website.FullPath)</Source>
<Destination>%(PackageFile.FullPath)</Destination>
</PropertyGroup>
<MakeDir Directories="$(PackageDir)"/>
<Exec Command='"@(MsDeploy)" -verb:sync -source:iisApp="$(Source)" -dest:package="$(Destination)"'/>
</Target>
<Target Name="DeployToDev" DependsOnTargets="Package">
<PropertyGroup>
<WebServerName>DEVSERVER</WebServerName>
<Source>%(PackageFile.FullPath)</Source>
</PropertyGroup>
<Exec Command='"@(MsDeploy)" -verb:sync -source:package="$(Source)" -dest:iisApp="Default Web Site", computerName=$(WebServerName),username=,password='/>
</Target>
</Project>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0"
DefaultTargets="Compile">
<UsingTask AssemblyFile="C:\svn\project\src\packages\ThirdParty\MSBuildCommunityTasks\AsyncExec.dll" TaskName="AsyncExec.AsyncExec"/>
<UsingTask AssemblyFile="C:\svn\project\src\packages\ThirdParty\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" TaskName="MSBuild.Community.Tasks.XmlRead" />
<ItemGroup>
<SolutionRoot Include="."/>
<BuildArtifacts Include=".\buildartifacts\"/>
<SolutionFile Include="..\src\Project.sln"/>
<MsDeploy Include="..\src\packages\MSdeploy2\msdeploy.exe"/>
<PackageFile Include=".\buildartifacts\package\Project.zip"/>
<Website Include=".\buildartifacts\_PublishedWebsites\Project.Website"/>
</ItemGroup>
<Target Name="Clean">
<RemoveDir Directories="@(BuildArtifacts)"/>
</Target>
<Target Name="Init" DependsOnTargets="Clean">
<MakeDir Directories="@(BuildArtifacts)"/>
</Target>
<Target Name="Compile" DependsOnTargets="Init">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
</PropertyGroup>
<MSBuild Projects="@(SolutionFile)" Properties="OutDir=%(BuildArtifacts.FullPath);
Configuration=$(Configuration)"/>
</Target>
<Target Name="Package" DependsOnTargets="Compile">
<PropertyGroup>
<PackageDir>%(PackageFile.RootDir)%(PackageFile.Directory)</PackageDir>
<Source>%(Website.FullPath)</Source>
<Destination>%(PackageFile.FullPath)</Destination>
</PropertyGroup>
<MakeDir Directories="$(PackageDir)"/>
<Exec Command='"@(MsDeploy)" -verb:sync -source:iisApp="$(Source)" -dest:package="$(Destination)"'/>
</Target>
<Target Name="DeployToDev" DependsOnTargets="Package">
<PropertyGroup>
<WebServerName>DEVSERVER</WebServerName>
<Source>%(PackageFile.FullPath)</Source>
</PropertyGroup>
<Exec Command='"@(MsDeploy)" -verb:sync -source:package="$(Source)" -dest:iisApp="Default Web Site", computerName=$(WebServerName),username=,password='/>
</Target>
</Project>
Thursday, August 9, 2012
Tuesday, July 10, 2012
ASP.NET MVC Remote Validation
public class TimeCard : IValidatableObject
{
...
[Remote("CheckUserName", "Home", ErrorMessage="Username is invalid")]
public string UserName{get; set;}
...
}
public class HomeController : Controller
{
...
public JsonResult CheckUsername(string username)
{
var result = false;
if(username == "tkhuc")
{
result = true;
}
return Json(result, JsonRequestBehavior.AllowGet);
}
{
...
[Remote("CheckUserName", "Home", ErrorMessage="Username is invalid")]
public string UserName{get; set;}
...
}
public class HomeController : Controller
{
...
public JsonResult CheckUsername(string username)
{
var result = false;
if(username == "tkhuc")
{
result = true;
}
return Json(result, JsonRequestBehavior.AllowGet);
}
ASP.NET MVC Custom Client Validation
Implement IClientValidatable
Implement a jQuery validation method
Implement an unobtrusive adapter
public class GreaterThanDateAttribute : ValidationAttribute, IClientValidatable
{
...
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "greater";
rule.ValidationParameters.Add("other", otherPropertyName);
yield return rule;
}
customvalidation.js
/// <reference path="jquery-1.4.4-vsdoc.js" />
/// <reference path="jquery.validate-vsdoc.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
jQuery.validator.addMethod("greater", function(value, element, param)
{
return Date.parse(value) > Date.parse($(param).val());
});
jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options){
options.rules["greater"] = "#" + options.params.other;
options.messages["greater"] = options.message; // ~ rule.ErrorMessage
});
Generated html output
<input class="text-box-single-line" id="EndDate" name="EndDate" type="text" value="1/1/2010 12:00:00 AM"
data-val="true"
data-val-greater="EndDate must be greater than StartDate"
data-val-greater-other="StartDate"
/>
Implement a jQuery validation method
Implement an unobtrusive adapter
public class GreaterThanDateAttribute : ValidationAttribute, IClientValidatable
{
...
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "greater";
rule.ValidationParameters.Add("other", otherPropertyName);
yield return rule;
}
customvalidation.js
/// <reference path="jquery-1.4.4-vsdoc.js" />
/// <reference path="jquery.validate-vsdoc.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
jQuery.validator.addMethod("greater", function(value, element, param)
{
return Date.parse(value) > Date.parse($(param).val());
});
jQuery.validator.unobtrusive.adapters.add("greater", ["other"], function(options){
options.rules["greater"] = "#" + options.params.other;
options.messages["greater"] = options.message; // ~ rule.ErrorMessage
});
Generated html output
<input class="text-box-single-line" id="EndDate" name="EndDate" type="text" value="1/1/2010 12:00:00 AM"
data-val="true"
data-val-greater="EndDate must be greater than StartDate"
data-val-greater-other="StartDate"
/>
ASP.NET MVC Client Validation
<script src="jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="jquery.validate.min.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
Global Settings
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavascriptEnabled" value="true"/>
</appSettings>
Page-level Settings
@Html.EnableClientValidation(false/true)
@Html.EnableUnobtrusiveJavascript(false/true)
Unobtrusive Javascript Validation
<input id="ConfirmHours" name="ConfirmHours" type="text value="0" class="text-box-single-line"
data-val="true"
data-val-equalto="ConfirmHours and Hours do not match."
data-val-equalto-other="*.Hours"
data-val-number="The field ConfirmHours must be a number."
data-val-range="The field ConfirmHours must be between 1 and 120."
data-val-range-max="120"
data-val-range-min="1"
data-val-required="The ConfirmHours field is required."
/>
<span class="field-validation-valid" data-valmsg-for="ConfirmHours" data-valmsg-replace="true"/>
<script src="jquery.validate.min.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
Global Settings
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavascriptEnabled" value="true"/>
</appSettings>
Page-level Settings
@Html.EnableClientValidation(false/true)
@Html.EnableUnobtrusiveJavascript(false/true)
Unobtrusive Javascript Validation
<input id="ConfirmHours" name="ConfirmHours" type="text value="0" class="text-box-single-line"
data-val="true"
data-val-equalto="ConfirmHours and Hours do not match."
data-val-equalto-other="*.Hours"
data-val-number="The field ConfirmHours must be a number."
data-val-range="The field ConfirmHours must be between 1 and 120."
data-val-range-max="120"
data-val-range-min="1"
data-val-required="The ConfirmHours field is required."
/>
<span class="field-validation-valid" data-valmsg-for="ConfirmHours" data-valmsg-replace="true"/>
Data Validation using Data Annotations
Data Annotations
[Required()][StringLength(25)]
[Range(1,120)]
public int Hours{get; set;}
[Compare("Hours")]
public int ConfirmHours{get; set;}
<div class="editor-label">
@Html.LabelFor(model=>model.ConfirmHours, "Please confirm the hours worked")
</div>
<div class="editor-field">
@Html.EditorFor(model=>model.ConfirmHours)
@Html.ValidationMessageFor(model=>model)
</div>
Custom Validation Attributes
public class GreaterThanDateAttribute : ValidationAttribute
:base("{0} must be greater than {1}")
{
public string OtherPropertyName{get; set;}
public GreaterThanDateAttribute(string otherPropertyName)
{
OtherPropertyName = otherPropertyName;
}
public override string FormatErrorMessage(string name)
{
return String.Format(ErrorMessageString, name, otherPropertyName);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var otherPropertyInfo = validationContext.ObjectType.GetProperty(otherPropertyName);
var otherDate = (DateTime)otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
var thisDate = (DateTime)value;
if(thisDate <= otherDate) //failed
{
var message = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(message);
}return null; //succeeded
}
}
public DateTime StartDate{get; set;}
[GreaterThanDate("StartDate")]
public DateTime EndDate{get; set;}
Sunday, July 8, 2012
MVC 3 Child Output Caching
Controllers\HomeController.cs
public class HomeController : Controller
{
[OutputCache(Duration = 60)]
public ActionResult Index()
{
var model = DateTime.Now;
return View(model);
}
[ChildActionOnly]
[OutputCache(Duration = 10)]
public PartialViewResult CurrentTime(){
var model = DateTime.Now;
return PartialView(model);
}
}
Views\Home\CurrentTime.cshtml
@model DateTime
<p>This is the child action result, current time is: @Model.ToLongTimeString()</p>
Views\Home\Index.cshtml
@model DateTime
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<div>This is the index view for Home, rendering at time: @Model.ToLongTimeString()</div>
<div>@Html.Action("CurrentTime")</div>
public class HomeController : Controller
{
[OutputCache(Duration = 60)]
public ActionResult Index()
{
var model = DateTime.Now;
return View(model);
}
[ChildActionOnly]
[OutputCache(Duration = 10)]
public PartialViewResult CurrentTime(){
var model = DateTime.Now;
return PartialView(model);
}
}
Views\Home\CurrentTime.cshtml
@model DateTime
<p>This is the child action result, current time is: @Model.ToLongTimeString()</p>
Views\Home\Index.cshtml
@model DateTime
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<div>This is the index view for Home, rendering at time: @Model.ToLongTimeString()</div>
<div>@Html.Action("CurrentTime")</div>
MVC Request Validation
Be careful when sending HTML to server.
[ValidateInput(false)] - turn off all verification
[AllowHtml] - granular verification for view model
[ValidateInput(false)] - turn off all verification
[AllowHtml] - granular verification for view model
MVC 3 Action Results
HttpNotFoundResult
public ActionResult Results()
{
return HttpNotFound();
}
HttpRedirectResult
public ActionResult Results()
{
return RedirectPermanent("http://google.com");
}
HttpStatusCodeResult
public AtionResult Results()
{
return HttpStatusCodeResult(415, "Media type not recognized");
}
public ActionResult Results()
{
return HttpNotFound();
}
HttpRedirectResult
public ActionResult Results()
{
return RedirectPermanent("http://google.com");
}
HttpStatusCodeResult
public AtionResult Results()
{
return HttpStatusCodeResult(415, "Media type not recognized");
}
Global Filters
Controllers\HomeController.cs
public class HomeController : Controller
{
public ActionResult Index()
{
throw new InvalidOperationException();
return View();
}
Views\Shared\Error.cshtml
<h2>Sorry, an error occurred while processing your request.</h2>
Global.asax.cs
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
protected void Application_Start()
{
RegisterGlobalFilters(GlobalFilters.Filters);
}
Web.config
<system.web>
<customErrors mode="On"/>
....
Action filters: [Authorize], [HandleError]
Custom Action Filters
public class LogAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext){}
public override void OnActionExecuted(ActionExecutedContext filterContext){}
public override void OnResultExecuting(ResultExecutingContext filterContext){}
public override void OnResultExecuted(ResultExecutedContext filterContext){}
}
public class HomeController : Controller
{
public ActionResult Index()
{
throw new InvalidOperationException();
return View();
}
Views\Shared\Error.cshtml
<h2>Sorry, an error occurred while processing your request.</h2>
Global.asax.cs
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
protected void Application_Start()
{
RegisterGlobalFilters(GlobalFilters.Filters);
}
Web.config
<system.web>
<customErrors mode="On"/>
....
Action filters: [Authorize], [HandleError]
Custom Action Filters
public class LogAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext){}
public override void OnActionExecuted(ActionExecutedContext filterContext){}
public override void OnResultExecuting(ResultExecutingContext filterContext){}
public override void OnResultExecuted(ResultExecutedContext filterContext){}
}
Sunday, June 3, 2012
Testing the Sad Path
When_passing_null_measurements.cs
using NUnit.Framework;namespace Domain.Tests.AveragingCalculator_Tests.SadPath
{
[Category("AveragingCalculator")]
public class When_passing_null_measurements
{
private AveragingCalculator _averageCalculator;
[SetUp]
public void Setup()
{
_averageCalculator = new AveragingCalculator();
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void When_measurement_is_null()
{
var measurements = Mother.Get4Measurements();
measurements.Add(null);
_averageCalculator.Aggregate(measurements);
}
}
AveragingCalculator.cs
namespace Domain{
public class AveragingCalculator : IAggregateCalculator
{
if(measurements.Contains(null))
{
throw new ArgumentNullException();
}
return new Measurement()
{
HighValue=measurements.Average(m=>m.HighValue),
LowValue=measurements.Average(m=>m.LowValue)
};
}
Test Project Structure
Solution
- Domain
- AggregationType.cs
- AveragingCalculator.cs
- IAggregateCalculator.cs
- IGrouper.cs
- Measurement.cs
- MeasurementAggregator.cs
- ModalCalculator.cs
- SizeGrouper.cs
- Domain.Tests
- References
- Domain
- AveragingCalculator_Tests
- SadPath
- When_passing_null_measurements.cs
- When_measurements_are_null()
- When_measurent_is_null()
- When_averaging_4_numbers.cs
- When_averaging_several_numbers.cs
- MeasurementAggregator_Tests
- When_aggregating_four_measurements.cs
- Mother.cs
Thursday, May 24, 2012
LINQPad
string[] names = {"Michael", "Long"};
IEnumerable<string> query = names
.Where(n=>n.Contains("o"))
.OrderBy(n=>n.Length)
.Select(n=>n.ToUpper());
query.Dump();
// same query as above
IEnumerable<string>filtered = names.Where(n=>n.Contains("o"));
IEnumerable<string>sorted = filtered.OrderBy(n=>n.Length);
IEnumerable<string>finalQuery = sorted.Select(n=>n.ToUpper());
filtered.Dump("Filtered");
sorted.Dump("Sorted");
finalQuery.Dump("FinalQuery");
IEnumerable<string> query = names
.Where(n=>n.Contains("o"))
.OrderBy(n=>n.Length)
.Select(n=>n.ToUpper());
query.Dump();
// same query as above
IEnumerable<string>filtered = names.Where(n=>n.Contains("o"));
IEnumerable<string>sorted = filtered.OrderBy(n=>n.Length);
IEnumerable<string>finalQuery = sorted.Select(n=>n.ToUpper());
filtered.Dump("Filtered");
sorted.Dump("Sorted");
finalQuery.Dump("FinalQuery");
LINQ Dynamic Query
using System.Linq.Dynamic
var repository = new EmployeeRepository();
var query = repository.GetAll()
.AsQueryable()
.OrderBy("Name")
.Where("DepartmentID = 1");
var repository = new EmployeeRepository();
var query = repository.GetAll()
.AsQueryable()
.OrderBy("Name")
.Where("DepartmentID = 1");
LINQ Joins
var employeeRepository = new EmployeeRepository();
var departmentRepository = new DepartmentRepository();
Inner Join (Normal)
var employees =from employee in employeeRepository.GetAll()
join department in departmentRepository.GetAll()
on employee.DepartmentID equals department.ID
select new {employee.Name, Department = department.Name};
Left Join (Grouping on Departments)
var query =from d in departmentRepository.GetAll()
join e in employeesRepository.GetAll()
on d.ID equals e.DepartmentID
into ed
select new
{
Department = d.Name,
Employees = ed};
foreach(var group in query)
{
Console.WriteLine(group.Department);
foreach(var employee in group.Employees)
{
Console.WriteLine("\t" + employee.Name);
}
}
Cross Join (for completeness)
var employees =
from employee in employeeRepository.GetAll()
join department in departmentRepository.GetAll()
select new {employee.Name, Department = department.Name};
LINQ Grouping and Projecting
var repository = new EmployeeRepository();
from e in repository.GetAll()
group e by e.DepartmentID
into eGroup
orderby eGroup.Key descending
where eGroup.Key < 3
select new
{
DepartmentID = eGroup.Key,
Count = eGroup.Count(),
Employees = eGroup
};
Comprehensive Query Syntax
var queryByDepartment =from e in repository.GetAll()
group e by e.DepartmentID
into eGroup
orderby eGroup.Key descending
where eGroup.Key < 3
select new
{
DepartmentID = eGroup.Key,
Count = eGroup.Count(),
Employees = eGroup
};
Extension Methods with Lambda Expressions
var queryByDepartment2 =
repository.GetAll()
.GroupBy(e=>e.DepartmentID)
.OrderByDescending(g=>g.Key)
.Where(g=>g.Key < 3)
.Select(g=>
new
{
DepartmentID = g.Key,
Count = g.Count(),
Employees = g
});
foreach(var group in queryByDepartment2)
{
{
Console.WriteLine("DID: {0}, Count: {1}",
group.DepartmentID,
group.Count);
foreach(var employee in group.Employees)
{
Console.WriteLine("\t{0}:{1}", employee.DepartmentID, employee.Name);
}
}
Restrictions for Implicit Typing
The following var statements result in compiler errors:
var i;
var j, k = 0;
var n = null;
var number = "2";
int x = number + 1;
var i;
var j, k = 0;
var n = null;
var number = "2";
int x = number + 1;
Extension Methods with Lambda Expressions vs. Comprehensive Query Syntax
Employee[] employees = new Employee[]
{
new Employee{ID=1, Name="The"},
new Employee{ID=2, Name="Foo"}
};
//Employee the = Array.Find(employees, FindThePredicate);
Employee the = Array.Find(employees, e=>e.Name == "The");
from e in employees
where e.Name == "The"
orderby e.ID ascending
select e;
(from e in employees
where e.Name == "The"
orderby e.ID ascending
select e).First();
employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e);
employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e)
.First();
{
new Employee{ID=1, Name="The"},
new Employee{ID=2, Name="Foo"}
};
//Employee the = Array.Find(employees, FindThePredicate);
Employee the = Array.Find(employees, e=>e.Name == "The");
Comprehensive Query Syntax
Collection
IEnumerable<Employee> query1 =from e in employees
where e.Name == "The"
orderby e.ID ascending
select e;
Single Item
Employee query1 =(from e in employees
where e.Name == "The"
orderby e.ID ascending
select e).First();
Extension Methods with Lambda Expressions
Collection
IEnumerable<Employee> query2 =employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e);
Single Item
Employee query2 =employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e)
.First();
Action and Func Delegates and Lambda Expressions
private static void ActionAndFunc()
{
Action printEmptyLine = () => Console.WriteLine();
Action<int> printNumber = x => Console.WriteLine(x);
Action<int, int> printTwoNumbers = (x,y) =>
{
Console.WriteLine(x);
Console.WriteLine(y);
};
Func<DateTime> getTime = () => DateTime.Now;
Func<int, int> square = x => x*x;
Func<int, int, int> multiply = (x,y) => x*y;
printEmptyLine();
printNumber(6);
printTwoNumbers(2,3);
DateTime now = getTime();
int z = multiply(4,7);
}
{
Action printEmptyLine = () => Console.WriteLine();
Action<int> printNumber = x => Console.WriteLine(x);
Action<int, int> printTwoNumbers = (x,y) =>
{
Console.WriteLine(x);
Console.WriteLine(y);
};
Func<DateTime> getTime = () => DateTime.Now;
Func<int, int> square = x => x*x;
Func<int, int, int> multiply = (x,y) => x*y;
printEmptyLine();
printNumber(6);
printTwoNumbers(2,3);
DateTime now = getTime();
int z = multiply(4,7);
}
Wednesday, May 23, 2012
Named vs. Anonymous Method vs. Lambda Expressions
Named Method Predicate - passing method pointers
static void Main(string[] args){
Employee the = Array.Find(employees, FindThePredicate);
}
static bool FindThePredicate(Employee e)
{
return e.Name == "The";
}
Anonymous Method
static void Main(string[] args){
Employee the = Array.Find(employees,
delegate(Employee e)
{
return e.Name == "The";
}
);
}
Lambda Expression - anonymous method but with less code
static void Main(string[] args){
Employee the = Array.Find(employees, (e) => e.Name =="The");
}
Thursday, April 26, 2012
Wednesday, March 21, 2012
Subscribe to:
Posts (Atom)


