Complicated C# for learning purposes
I'm trying to read some of other people's code, both to help me learn C#, and also purely to develop my ability to understand other people's code, but a lot of what I've found online to look at is both very long, and relatively simple. I wonder if anyone could point me to something short but more complex, pr开发者_如何学Goeferably including less common uses of the language.
(It doesn't need to do anything sensible, so long as it does something. Something entirely pointless, like a C# equivilent of the XSLT Mandelbrot, would be perfectly fine)
Eric Lippert has recently been writing a series on graph colouring on his blog. This may well be something to sink your teeth into as it's a multi-part series that should allow you to work your way from simple to brain-meltingly-ouch as he progresses with explaining graph colouring. =)
I'd recommend looking at the Effective C# books. They'll help you learn more complex uses of the language.
Take a look at the mono source code - many of the BCL classes are implemented and you are sure to learn something :)
There are also many open source .NET projects out there that are not small and simple applications that you can look at.
Here are some off the top of my head:
- MonoDevelop - a .NET IDE
- nHibernate - an ORM
- Pinta - image manipulation a la gimp
Raytracing in one LINQ statement, from Luke Hoban's blog, jumps immediately to mind.
Take a look at the .NET framework assemblies themselves using the .NET Reflector. There is a bunch of really great stuff in there and has helped me a lot during my learning.
Many times I have thought to myself how Microsoft has done certain things in the framework and I was easily able to find the answers right within their source.
Check out Coding4Fun. It's a mix of .Net languages and some (most) of the projects are really cool. XNA Creators Club is pretty cool as well... plenty of samples and it you have an XBox360 or a Zune you can write games for them as well.
How about this?
private Element ReadMemberExpression()
{
var queue = new Queue<Element[]>();
var newDepth = 0;
var argsCount = 0;
_scanner.CreateRestorePoint();
while (true)
{
_scanner.CreateRestorePoint();
{
var a = ReadArguments();
if (a != null)
{
argsCount++;
if (argsCount > newDepth)
{
_scanner.Restore();
break;
}
queue.Enqueue(new[] { default(Element), default(Element), a });
_scanner.DeleteRestorePoint();
continue;
}
}
_scanner.DeleteRestorePoint();
var pe = ReadPrimaryExpression();
if (pe != null)
{
queue.Enqueue(new[] { pe });
continue;
}
var fe = ReadFunctionExpression();
if (fe != null)
{
queue.Enqueue(new[] { fe });
continue;
}
if (_scanner.MatchNext(Grammar.New))
{
newDepth++;
queue.Enqueue(new[] { Grammar.New });
}
else if (_scanner.Match(Grammar.LeftSquareBracket))
{
var e = ReadExpression();
if (e == null)
{
throw new ParseException();
}
if (!_scanner.MatchNext(Grammar.RightSquareBracket))
{
throw new ParseException();
}
queue.Enqueue(new[]{default(Element), Grammar.LeftSquareBracket, e, Grammar.RightSquareBracket});
}
else if (_scanner.Match(Grammar.FullStop))
{
if (!_scanner.MatchNext(ElementType.IdentifierName))
{
throw new ParseException();
}
queue.Enqueue(new[] { default(Element), Grammar.FullStop, _scanner.Current });
}
else
{
_scanner.Unwind();
break;
}
}
if (queue.Count == 0)
{
_scanner.DeleteRestorePoint();
return null;
}
else
{
var element = default(Element);
var children = queue.Dequeue();
while (children[0] == Grammar.New)
{
children = queue.Dequeue();
}
element = new Element(ElementType.MemberExpression, children);
while (queue.Count > 0)
{
children = queue.Dequeue();
if (children.Length == 3 && children[2].Type == ElementType.Arguments)
{
newDepth--;
children[0] = Grammar.New;
children[1] = element;
element = new Element(ElementType.MemberExpression, children);
}
else
{
children[0] = element;
element = new Element(ElementType.MemberExpression, children);
}
}
if (newDepth > 0)
{
_scanner.Restore();
return null;
}
_scanner.DeleteRestorePoint();
return element;
}
}
It's not terribly complex, but may be briefly entertaining -- Mads Torgersen has implemented a fixed-point combinator in C# here:
http://blogs.msdn.com/b/madst/archive/2007/05/11/recursive-lambda-expressions.aspx
This may be an obvious suggestion, but I would checkout the articles on CodeProject.com. You can search for specific articles relevant to C#, and the contributors generally do a great job of explaining their code.
For instance, here is an article on creating a Mandelbrot set in C# (though this may not be as complex as you might be looking for).
Other than that, I would take a peak inside any C# opensource projects you may find via Google.
精彩评论