Recently I came across ACM’s Software Engineering Code of Ethics and Professional Practice. One of the things I’ve tried to push around here is the idea that we as software engineers must constantly strive to stay current in our ever changing world. Like a doctor who must stay current with the latest medical procedures and drugs we as software engineers must stay current with the latest language features and APIs. It’s nice, egotistically speaking, to see that other people share my opinions on the matter
. Though I know this was created in 1999 I don’t think a lot of people are familiar with it. I’d recommend reading the full version at the link above but here is the short version:
Software Engineering Code of Ethics and Professional Practice (Short Version)
PREAMBLE
The short version of the code summarizes aspirations at a high level of the abstraction; the clauses that are included in the full version give examples and details of how these aspirations change the way we act as software engineering professionals. Without the aspirations, the details can become legalistic and tedious; without the details, the aspirations can become high sounding but empty; together, the aspirations and the details form a cohesive code.
Software engineers shall commit themselves to making the analysis, specification, design, development, testing and maintenance of software a beneficial and respected profession. In accordance with their commitment to the health, safety and welfare of the public, software engineers shall adhere to the following Eight Principles:
1. PUBLIC – Software engineers shall act consistently with the public interest.
2. CLIENT AND EMPLOYER – Software engineers shall act in a manner that is in the best interests of their client and employer consistent with the public interest.
3. PRODUCT – Software engineers shall ensure that their products and related modifications meet the highest professional standards possible.
4. JUDGMENT – Software engineers shall maintain integrity and independence in their professional judgment.
5. MANAGEMENT – Software engineering managers and leaders shall subscribe to and promote an ethical approach to the management of software development and maintenance.
6. PROFESSION – Software engineers shall advance the integrity and reputation of the profession consistent with the public interest.
7. COLLEAGUES – Software engineers shall be fair to and supportive of their colleagues.
8. SELF – Software engineers shall participate in lifelong learning regarding the practice of their profession and shall promote an ethical approach to the practice of the profession.
This Code may be published without permission as long as it is not changed in any way and it carries the copyright notice. Copyright (c) 1999 by the Association for Computing Machinery, Inc. and the Institute for Electrical and Electronics Engineers, Inc.
September 11th, 2009 in
C# |
No Comments
Oracle’s statement to Sun Customers.
What? No mention of Java. I really couldn’t care about Solaris or SPARC. What is the future of Java?
September 10th, 2009 in
Uncategorized | tags:
Java,
Oracle |
No Comments
Here’s some nice .Net 4.0 stuff on the way. I’ve been working on some poker tournament software with a lot of the new 4.0 features in mind. Once I have a couple of posts ready I’ll throw them up.
Thanks,
Brian
August 31st, 2009 in
C# | tags:
.Net 4.0,
C# |
No Comments
Between keeping up with what’s coming for .Net 4.0 as well as the end of a large DOD contract I’ve been a bit busy (and no developer fatigue, just busy
). But don’t fret loyal readers, more will be coming soon.
Until then here is a bit of xaml for self-referencing bindings.
<TextBlock
Grid.Column="1"
Width="75"
Foreground="{StaticResource ActiveTabForeground}"
TextWrapping="NoWrap"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Text}"
Name="txtHeader"/>
As you can see I often use these with TextBlocks where I’m using text trimming. The reason being that, with text trimming, the text gets cut short if it exceeds the width of the textblock. This way users will be able to mouse over the textblock and get the tooltip containing the full value.
Where else would this be useful? Well, um, I don’t know since I only use this with tooltips on TextBlocks. But it is certainly helpful for that.
Enjoy,
Brian
June 29th, 2009 in
C# |
No Comments
In the recent Visual Studio magazine I saw the following survey:
| Do you sense developer fatigue due to the pace of Microsoft Technology introductions? |
| Yes, some fatigue |
45% |
| No, little or no fatigue |
26% |
| Yes, significant fatigue |
24% |
| Don’t know |
5% |
(I love kicking it ol’school and using tables)
To the 26% that said no I say, “Good, you’re doing your job.” To the rest of you, “Get to work.”
I don’t often write opinion pieces preferring to keep the focus of this blog more on tutorial type posts, maybe because I don’t really consider myself any real authority. I do my job and in the course of my job I learn a lot that I want to pass on to other people.
So why start now? Well, this survey struck a nerve for me. Maybe it’s because this has some fingers in my post about Oracle and Java. In that post I reveled in the fact that Microsoft is able to keep the .Net framework moving forward at a fast pace and that, relative to .Net, Java has become fairly stagnant.
In Jeff Atwood’s post, The Two Types of Programmers he discusses the two types of programmers as mentioned in an article by Ben Collins-Sussman which says there are two classes of programmers, the “20%” and the “80%” programmers.
To this I have a serious problem. I spend a great deal of time reading the latest programming books, blogs and magazines. I do so because I want to stay current in my field. If I was doctor it would be expected that I would stay up-to-date on the latest research and trends in the medical fields. So should we as programmers.
Our job is to be the best programmers we can be. Fatigue should be irrelevant. Even if you are working in a world were the language features and APIs aren’t moving forward there is still a lot you can do. Read up on patterns and anti-patterns, if you haven’t read Code Complete, do so. I find the idea that programmers are perfectly happy to rest on their laurels completely ridiculous. Strive to become a better programmer, push yourself and your knowledge. As you become better at your job you will become a better person all-around. Knowledge is power.
If you stay current fatigue isn’t an issue. By keeping current incrementally there won’t be any fatigue. Start reading up on .Net 4.0 right now. By the time .Net 4.0 releases you will be pretty caught up and boom!, no more fatigue.
You may say, “Well, my job is to use this or that API or SDK. Knowing anything outside of that is irrelevant.” To that I’m calling “Bullshit!” It’s not about just writing code. If being a programmer was just about writing code then anybody could be a programmer. Writing code is easy. Writing code cleanly, efficiently so it’s easy to maintain, now that takes some skill. The best way to do so is to stay current.
Saying that you’re experiencing “fatigue due to the pace of Microsoft Technology introductions” is a serious cop-out. Staying current is your job because the more current you are the better programmer you are. If I was a fry-cook I’d want to be the best damn fry-cook on the planet, learn the lingo, find the right temperature for the grill so it cooks the eggs and burgers efficiently, work on recipes that taste good and can cook fast. I’m not a fry-cook, however, I’m a computer programmer. Being the best programmer I can be means that I have to stay current on new technology. Screw fatigue.
Thank you, that’s my time
high-pitched whine as I drop the microphone
May 19th, 2009 in
C# |
4 Comments
As I’m sure you can tell by the title of this post that it is about deferred execution in LINQ. When a LINQ query (I know, it’s like saying, “NIC card” or “ATM machine”) is created the values are not immediatly determined. Only when the list is utilized are the results determined.
This bit me at first so hopefully with this it won’t bite you.
If you have:
List<Product> products = new List<Product>();
products.Add(new Product { Id = 1, Name = "Cheese", Quantity = 2 });
products.Add(new Product { Id = 2, Name = "Wine", Quantity = 2 });
products.Add(new Product { Id = 3, Name = "Crackers", Quantity = 0 });
var zeroInStock = from product in products
where product.Quantity == 0
select product;
foreach (var stock in zeroInStock)
{
products.Remove(stock);
}
you will get:
InvalidOperationException was unhandled. Collection was modified; enumeration operation may not execute.
This is due to the deferred execution of LINQ. The results of zeroInStock are not calculated until you need them. The problem is that if you attempt to remove an item from the list in which the result originated from the original list is now not valid for the LINQ query. So how do you combat this? With ToList(), ToArray() and ToDictionary().
List<Product> products = new List<Product>();
products.Add(new Product { Id = 1, Name = "Cheese", Quantity = 2 });
products.Add(new Product { Id = 2, Name = "Wine", Quantity = 2 });
products.Add(new Product { Id = 3, Name = "Crackers", Quantity = 0 });
var zeroInStock = (from product in products
where product.Quantity == 0
select product).ToList();
foreach (var stock in zeroInStock)
{
products.Remove(stock);
}
Now this code works. In this example ToList() and ToArray() could have been used interchangbly since we’re utilizing var but you may need one over the other. By calling ToList() or ToArray() it forces execution of the query. This means that now you can change the original list all you want without any issues.
ToDictionary() works a bit different. You have to specify a lambda expression to detemine what the key should be for each given result. Here’s the ToDictionary() example:
List<Product> products = new List<Product>();
products.Add(new Product { Id = 1, Name = "Cheese", Quantity = 2 });
products.Add(new Product { Id = 2, Name = "Wine", Quantity = 2 });
products.Add(new Product { Id = 3, Name = "Crackers", Quantity = 0 });
var zeroInStock = (from product in products
where product.Quantity == 0
select product.ToDictionary(x => x.Name);
foreach (var stock in zeroInStock)
{
products.Remove(stock.Value);
}
You can see here the lambda expression means that the generated dictionary will be made of KeyValuePair<string, Product>. Since the product is now the value of the KeyValuePair the foreach that removes products with zero in stock now uses the Value.
If you are going from dictionary to dictionary as in:
Dictionary<int, Product> products = new Dictionary<int, Product>();
products.Add(1, new Product { Id = 1, Name = "Cheese", Quantity = 2 });
products.Add(2, new Product { Id = 2, Name = "Wine", Quantity = 2 });
products.Add(3, new Product { Id = 3, Name = "Crackers", Quantity = 0 });
var zeroInStock = (from product in products
where product.Value.Quantity == 0
select product).ToDictionary(x => x.Key);
foreach (var stock in zeroInStock)
{
products.Remove(stock.Key);
}
you will most likely want to just use the existing key as I have above. Now, this doesn’t mean you can’t change the key but for my purposes I just used the existing key since I can use that to just remove from the dictionary.
That’s all for now. Leave me a comment if you have any questions.
Brian
Over at Oren’s Blog there was the following comment:
Alberto:
So what. I don’t care much what the writer says. Java is open source, so Oracle can’t “own” it in the sense they can’t control it.
to which I responded:
@Alberto,
Java itself is not opensource only the JDK. This means if you want to help to make changes to the core libraries you can but if you got a wild hair for some reason and wanted to figure out how to add LINQ to Java you couldn’t. See http://www.sun.com/software/opensource/java/faq.jsp#b8
This is an important distinction. The JDK is opensource, not Java. This means the future of Java is in the hands of Oracle and it scares me. Development on the Oracle DB itself has been rather stagnant. I’m not saying that there haven’t been new features added, just that Oracle hasn’t been making any big leaps forward.
I’ve had the unique opportunity for the last 6 years to develop professionally in Java and the last 5 years in C#, a man of both worlds. When C# first came out I was thinking, so what? I can do that in Java and do it easier and cleaner. C# had a lot of catching up to do. Fast forward 5 years and Java is so far behind the curve now. Development of the Java language has become stagnant. Like the Oracle DB, new features are added sure, but there haven’t been any significant leaps forward. Java has simply fallen behind. I just hope Oracle doesn’t do to Java what it has done to it’s DB and let it die a slow death. As pointed out by Andrew nearly all of Oracle’s business is with the government, and having worked on some government contracts I can tell you that is starting to slip.
As a new generation of IT moves into places of power they simply are not as enamored with Oracle as the old guard were and they are willing to look to other solutions.
So what does this mean? C, C++ and Perl haven’t had any new features for a long time. Does a language need to make leaps forward? C, C++ and Perl live in different worlds with different purposes then Java and .Net. Sure there are some cross purposes but for the most part they are separate. Java has to continue to innovate if it wants to stay a viable mainstream language. I hope that Oracle can bring innovation back to Java and yet worry that it doesn’t really care.
Brian
In thinking back, the only part of my comment I disagree with is:
having worked on some government contracts I can tell you that is starting to slip.
The reason I disagree with it is because, at this moment, the federal government and the DOD are still firmly entrenched in the idea that Oracle is the only way to go. So basically I’m saying that things aren’t starting to slip, at least not right now.
But I do firmly believe the next part of my comment:
As a new generation of IT moves into places of power they simply are not as enamored with Oracle as the old guard were and they are willing to look to other solutions.
My point here is that I think Oracle cares about Java because their tools are written in Java. But that is it’s only extent. Now that the JDK is opensourced I’m sure we’ll see some movement in the JDK but very little, if not nothing, in the Java language itself. This is really a shame.
There is no doubt that Java rules in the web application market against .Net and ASP.Net, just as there is no doubt that Apache rules in the web server market against IIS. Maybe that is fine for Java. Maybe Sun wants it to be consigned to a subset of the development market. But there are some heavy hitters in that market, Ruby, PHP, and Perl to name a few.
So why not try and carve out a significant share in all markets? Java has never truly had a significant share in the desktop application market. I feel it was held back by how bad AWT and then Swing were. In Java 6 it seems like they’ve tried to make some steps forward with the new desktop APIs but it doesn’t seem like that is enough.
6 years ago Java was an innovation. Now it’s merely stagnant. It’s APIs can’t keep up, it’s language features can’t keep up. With every new release of .Net I find it easier and easier to do everything. With every new release of Java I think, “That’s kind of cool but that doesn’t help me.”
There is a definite flaw there. I hope Oracle dumps a bunch of money into Java and really gets the development platform, from both the JDK and the language features perspective, kicked into high gear. It’s just that it seems that Oracle actually likes stagnation. If it ain’t broke, don’t fix it is their attitude. The problem is that, while that may work for the Oracle DB with their heavy paying government projects, it doesn’t work for Java.
Later,
Brian
April 23rd, 2009 in
Uncategorized | tags:
Java,
Oracle,
Sun |
4 Comments
I suppose for any serious software engineer one must read Code Complete. Last week I finished it and have been trying to think of how to write a review of it. I’ve decided to do so briefly.
Let me start off by saying I’m excited that I finished it. There is a lot of good information and there is no doubt that it is the standard for sound software developement principles. That being said, remember when you try to tackle this bood that it is a text book. Sure there are some interesting anecdotes about this and that. I suppose I should have been more thrilled about reading it but couldn’t drag myself to pour through it like I have some of my other software books. It took me a year to read Code Complete. During that time I re-read The Belgariad series, The Malloreon series, most of the Song of Ice and Fire series, and read for the first time Pro WPF in C# 2008, Effective C# and I’m almost done with More Effective C#.
So what am I saying? I know there are those of you out there that love Code Complete and read it voraciously like a good fiction novel. I couldn’t even read it like a good code book. Pro WPF in C# 2008 I read like a good fiction novel. I drank it in and loved it. Code Complete I just couldn’t do that with. As I said, it’s sound, solid developement principles I try to apply every day on the job. I learned a lot and will continue to try and apply the princibles of Code Complete. Simply because of that it is a reason to read the book.
If you’re like me and are struggling to get through Code Complete, spread it out, read a chapter and then take a break and read something else. There are 35 chapters in Code Complete. Read a chapter every two weeks, in between other books and it will take you just a bit over a year to read it.
What else can I say? 99% of the book makes perfect sense. Some of the code formatting seemed a bit off but I just let visual studio format my code for me. Ctrl-K + Ctrl-D, Baby!
Read it, grok it, follow it and your code will be better, cleaner and easier to maintain.
That’s all there it to it.
Brian
Okay, I know you think I’ve seriously hit the crack pipe here. Curly Braces, as I’m sure we all know, are fundamental to programming in most languages. This is true no more so then here in C#. We use them for if, for, using, do, while, namespace scope, class scope, method scope and getters and setters for parameters.
So how could I dare to say the {} is an often unused operator? Well, I’m specifically talking about a use of the operators in this case, not the operators themselves.
Did you know you can use curly braces by themselves? Take a look at this:
public Window1()
{
InitializeComponent();
{
int [] intList = { 1, 2, 3, 4, 5, 6 };
var evens = intList.Where(x => x % 2 == 0);
}
{
int[] intList = { 1, 2, 3, 4, 5, 6 };
var odds = intList.Where(x => x % 2 == 1);
}
}
Yes! That there are curly braces by themselves!
Why the hell would anyone want to do this? I find myself using them all the time when writing up samples where at http://www.formatexception.com. The reason is that I test all the sample code I post up here that I write. This has been a big help especially since it seems like a lot of the linq code here derives from msdn samples and, believe it or not, not all of them work.
What this means is that if I want to do a write-up on linq where I’m using the where method on IEnumerables (like above) I write the code surrounded by curly braces. Because each is it’s own scope, call it internal method scope if you will, there won’t be any name collisions. It’s like doing an if(true){} without the if(true), or like using the using keyword as in:
using(Stream ImageStream = new MemoryStream(File.ReadAllBytes(ImagePath)))
{
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ImageStream;
bi.EndInit();
Image imageFromFile = new Image() { Source = bi };
//dump image into wrap panel in form
imagePanel.Children.Add(imageFromFile);
}
except you don’t have to have a class the implements IDisposable.
So, where would you use this? If you’re real paticular (i.e. anal) about the your variable names. For instace the following code is not valid:
{
int [] intList = { 1, 2, 3, 4, 5, 6 };
var evens = intList.Where(x => x % 2 == 0);
}
int[] intList = { 7, 8, 9, 10, 11, 12 };
var odds = intList.Where(x => x % 2 == 1);
The reason is that the set of curly braces define a child scope but the second intlist exists in the parent scope. Sibling scopes can have variables of the same name but not parent/child scopes. If I really wanted my intList to be named “intList” and assuming it would only be needed within the child scope I could put a second set of curly braces around the other code and be free to name my intList to, um, “intList”.
I have never really found a use for this in production code to be honest. I use it a lot when writing up samples for my posts, but not in production code. I suppose if I was adamant about my variable names I would use it more and I think a few of you out there are. I, however, have no problem simply naming my second int list to intListForOdds.
So that is the curly braces and their often unused purpose.
Later,
Brian
Now that we’ve touched on “group by” lets throw in a couple of where clauses on the group by with any and all.
If you are really interested in all the data I have the code at the end of this post showing how I add all the products. Since this is just sample data I threw it in a list but chances are you’re going to be getting your list from some sort of DAL.
Let’s start with some lead up to “Any”.
Given:
string[] words = { "cow", "believe", "bread", "river", "receipt", "field" };
var wordsList =
from w in words
where w.Contains("ei")
select w;
we can see this gives a list of words that have “ei” in them. But what if we don’t care for the list? What if we just want to know if any of the words have “ei”? We can simplify life by using the Any on a list from linq and get a boolean.
bool iAfterE = words.Any(w => w.Contains("ei"));
is true.
“No kidding”
“Oh great, folks, if you don’t know already this is Ivan.”
“So next you’re going to tell me I can use the All method on lists to tell me if all of the words contain “ei”? Come on and give your audience some credit. If you’re head wasn’t stuck so far…”
“Ivan, I get the point, I’ll make this easy for all of us and give them the code.”
“And don’t you think this whole talking to yourself think is getting old? I mean come on!”
“You think you can do better?”
“Listen to yourself. You’re talking to me who just happens to me you. What does me doing any better have to do with anything? I am you. Wow, pull yourself together and get this overwith. We have a database rewrite to review today, implement tomorrow and then a week to recode the app for the new database, time to move on.”
“Fine, here” (Note: I couldn’t do it, it looked like crap when I just put up all the code. I have to break it up a little bit so I’m ignoring Ivan because it was just a bad suggestion.)
string[] words = { "cow", "believe", "bread", "river", "receipt", "field" };
var wordsList =
from w in words
where w.Contains("ei")
select w;
bool iAfterE = words.All(w => w.Contains("ei"));
As I’m sure you know, iAfterE is false as not all the words have “ei” in them.
List<Product> products = GetProductList();
var productGroups =
from p in products
group p by p.Category into g
where g.Any(p => p.UnitsInStock == 0)
select new { Category = g.Key, Products = g };
Console.WriteLine("\nFor Any:");
foreach (var group in productGroups)
{
Console.WriteLine("\nFor Category {0}:", group.Category);
foreach (var p in group.Products)
{
Console.Write("{0} with {1} units, ", p.ProductName, p.UnitsInStock);
}
}
In this first product group you can see that the where on the group by is only creating groups by category where any of the products in the category have 0 units in stock. This is key to the where with group by, only if the where is satisfied will the group be created. You will end up with:
For Any:
For Category Condiments:
Aniseed Syrup with 13 units, Chef Anton’s Cajun Seasoning with 53 units, Chef Anton’s Gumbo Mix with 0 units, Grandma’s Boysenberry Spread with 120 units, Northwoods Cranberry Sauce with 6 units, Genen Shouyu with 39 units,
For Category MeatPoultry:
Mishi Kobe Niku with 29 units, Alice Mutton with 0 units, Thüringer Rostbratwurst with 0 units, Perth Pasties with 0 units, Tourtière with 21 units,
For Category DairyProducts:
Queso Cabrales with 22 units, Queso Manchego La Pastora with 86 units, Gorgonzola Telino with 0 units, Mascarpone Fabioli with 9 units,
List<Product> products = GetProductList();
var productGroups =
from p in products
group p by p.Category into g
where g.All(p=> p.UnitsInStock > 0)
select new { Category = g.Key, Products = g };
Console.WriteLine("\nFor All:");
foreach (var group in productGroups)
{
Console.WriteLine("\nFor Category {0}:", group.Category);
foreach (var p in group.Products)
{
Console.Write("{0} with {1} units, ", p.ProductName, p.UnitsInStock);
}
}
For the second product group it is looking to make sure that all products in the group of a UnitsInStock of greater then 0 thus giving you:
For All:
For Category Seafood:
Ikura with 31 units, Konbu with 24 units, Carnarvon Tigers with 42 units, Nord-Ost Matjeshering with 10 units, Inlagd Sill with 112 units, Gravad lax with 11 units,
For Category Produce:
Uncle Bob’s Organic Dried Pears with 15 units, Tofu with 35 units, Rössle Sauerkraut with 26 units,
For Category Beverages:
Chai with 39 units, Chang with 17 units, Guaraná Fantástica with 20 units, Sasquatch Ale with 111 units, Steeleye Stout with 20 units,
Well, that’s a quick write up on any and all with group by. Time to start reviewing ERDs.
Brian
And here is GetProductList:
private List<Product> GetProductList()
{
List<Product> products = new List<Product>();
products.Add(new Product { ProductId = 10, ProductName = "Ikura", Category = "Seafood", UnitPrice = 31.0000, UnitsInStock = 31 });
products.Add(new Product { ProductId = 13, ProductName = "Konbu", Category = "Seafood", UnitPrice = 6.0000, UnitsInStock = 24 });
products.Add(new Product { ProductId = 18, ProductName = "Carnarvon Tigers", Category = "Seafood", UnitPrice = 62.5000, UnitsInStock = 42 });
products.Add(new Product { ProductId = 30, ProductName = "Nord-Ost Matjeshering", Category = "Seafood", UnitPrice = 25.8900, UnitsInStock = 10 });
products.Add(new Product { ProductId = 36, ProductName = "Inlagd Sill", Category = "Seafood", UnitPrice = 19.0000, UnitsInStock = 112 });
products.Add(new Product { ProductId = 37, ProductName = "Gravad lax", Category = "Seafood", UnitPrice = 26.0000, UnitsInStock = 11 });
products.Add(new Product { ProductId = 7, ProductName = "Uncle Bob's Organic Dried Pears", Category = "Produce", UnitPrice = 30.0000, UnitsInStock = 15 });
products.Add(new Product { ProductId = 14, ProductName = "Tofu", Category = "Produce", UnitPrice = 23.2500, UnitsInStock = 35 });
products.Add(new Product { ProductId = 28, ProductName = "Rössle Sauerkraut", Category = "Produce", UnitPrice = 45.6000, UnitsInStock = 26 });
products.Add(new Product { ProductId = 3, ProductName = "Aniseed Syrup", Category = "Condiments", UnitPrice = 10.0000, UnitsInStock = 13 });
products.Add(new Product { ProductId = 4, ProductName = "Chef Anton's Cajun Seasoning", Category = "Condiments", UnitPrice = 22.0000, UnitsInStock = 53 });
products.Add(new Product { ProductId = 5, ProductName = "Chef Anton's Gumbo Mix", Category = "Condiments", UnitPrice = 21.3500, UnitsInStock = 0 });
products.Add(new Product { ProductId = 6, ProductName = "Grandma's Boysenberry Spread", Category = "Condiments", UnitPrice = 25.0000, UnitsInStock = 120 });
products.Add(new Product { ProductId = 8, ProductName = "Northwoods Cranberry Sauce", Category = "Condiments", UnitPrice = 40.0000, UnitsInStock = 6 });
products.Add(new Product { ProductId = 15, ProductName = "Genen Shouyu", Category = "Condiments", UnitPrice = 15.5000, UnitsInStock = 39 });
products.Add(new Product { ProductId = 9, ProductName = "Mishi Kobe Niku", Category = "MeatPoultry", UnitPrice = 97.0000, UnitsInStock = 29 });
products.Add(new Product { ProductId = 17, ProductName = "Alice Mutton", Category = "MeatPoultry", UnitPrice = 39.0000, UnitsInStock = 0 });
products.Add(new Product { ProductId = 29, ProductName = "Thüringer Rostbratwurst", Category = "MeatPoultry", UnitPrice = 123.7900, UnitsInStock = 0 });
products.Add(new Product { ProductId = 53, ProductName = "Perth Pasties", Category = "MeatPoultry", UnitPrice = 32.8000, UnitsInStock = 0 });
products.Add(new Product { ProductId = 54, ProductName = "Tourtière", Category = "MeatPoultry", UnitPrice = 7.4500, UnitsInStock = 21 });
products.Add(new Product { ProductId = 11, ProductName = "Queso Cabrales", Category = "DairyProducts", UnitPrice = 21.0000, UnitsInStock = 22 });
products.Add(new Product { ProductId = 12, ProductName = "Queso Manchego La Pastora", Category = "DairyProducts", UnitPrice = 38.0000, UnitsInStock = 86 });
products.Add(new Product { ProductId = 31, ProductName = "Gorgonzola Telino", Category = "DairyProducts", UnitPrice = 12.5000, UnitsInStock = 0 });
products.Add(new Product { ProductId = 32, ProductName = "Mascarpone Fabioli", Category = "DairyProducts", UnitPrice = 32.0000, UnitsInStock = 9 });
products.Add(new Product { ProductId = 1, ProductName = "Chai", Category = "Beverages", UnitPrice = 18.0000, UnitsInStock = 39 });
products.Add(new Product { ProductId = 2, ProductName = "Chang", Category = "Beverages", UnitPrice = 19.0000, UnitsInStock = 17 });
products.Add(new Product { ProductId = 24, ProductName = "Guaraná Fantástica", Category = "Beverages", UnitPrice = 4.5000, UnitsInStock = 20 });
products.Add(new Product { ProductId = 34, ProductName = "Sasquatch Ale", Category = "Beverages", UnitPrice = 14.0000, UnitsInStock = 111 });
products.Add(new Product { ProductId = 35, ProductName = "Steeleye Stout", Category = "Beverages", UnitPrice = 18.0000, UnitsInStock = 20 });
return products;
}
March 17th, 2009 in
C# | tags:
LINQ |
2 Comments