Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Cancelbot
Nov 22, 2006

Canceling spam since 1928

Good point - I tend to go for constructor dependency injection (windsor or similar), but what I've been trying is a really convoluted way around that with no tangible benefits other than I reduce the risk of a NullReferenceException, which should have been spotted in my unit tests.

It was an interesting enough experiment anyway, I'd love to try and apply F# to something like ASP.NET MVC but the Razor stuff is still C# :smith:

Adbot
ADBOT LOVES YOU

ljw1004
Jan 18, 2005

rum

zokie posted:

What problem are you trying to solve exaclty? Embrace the null instead. Absolutely use nullables for keys and such. Using int? keys and the like has made my life so much easier. What you are doing just seems strange, and I really don't see any benefit to it.

For the next version of C# we're considering a feature that will make it less verbose to have to keep checking for nulls...

code:
var a = e?.x;

==> compiler turns this into something like ==>

var $temp = e;
var a = ($temp == null) ? null : $temp.x;
If e.x was a value-type like "int", then the type of "a" will become "int?", i.e. lifted to its nullable form. But if e.x was a reference-type like "string", then the type of "a" will just be string.

Mr. Crow
May 22, 2008

Snap City mayor for life

ljw1004 posted:

For the next version of C# we're considering a feature that will make it less verbose to have to keep checking for nulls...

code:
var a = e?.x;

==> compiler turns this into something like ==>

var $temp = e;
var a = ($temp == null) ? null : $temp.x;
If e.x was a value-type like "int", then the type of "a" will become "int?", i.e. lifted to its nullable form. But if e.x was a reference-type like "string", then the type of "a" will just be string.

I was going to post this and I sincerely hope it gets put in.

Milotic
Mar 4, 2009

9CL apologist
Slippery Tilde

wwb posted:

I haven't spent any measurable time with the new identiy framework though it looks good and I don't see why you couldn't easily roll your own plumbing for the raw ADO.NET bits.

I have done a number of AD backed authentication schemes in the past. Generally we found that the most successful model was to let AD be the authenticator and handle authorization in the app rather than also ride AD groups for that. In that context it often made sense to ride parts of the membership providers even though the users weren't necessarily living with in SQL server.

Thanks. We tend to rely on AD groups for authorisation due to Infosec requirements and most functionality tends to be restricted on a per-team basis. Based on this and everyone else's comments I'll leave out using ASP.NET Identity for now.

RangerAce posted:

I assume you're not going with EF because you'd have to refactor your DB schema for it? I've actually been thinking about migrating us to EF because I have a lot of low-experience junior devs working for us, and I want to remove learning SQL as a requirement for working on our backend code. But, then I'm worried about taking too much of a performance hit, etc. So, curious about your findings/thoughts.

If I can avoid refactoring our existing DB schema, I'd prefer it. But my chief objections to EF are the following:

  • Pulls back every column by default, even if you're not using them. Especially a problem if you're surfacing a table in a DB not maintained by you. If a column you're not actually referencing anywhere in your codebase goes from null to non-null (or vice versa) or disappears, everything blows up.
  • The SQL it generates is often very hard to read, with lots of Outer Apply keywords.
  • Hand cranked ADO.NET will beat it every time, and forces you to think about what columns you need.
  • In EF5+ the proxies they're using screws over debugger tooltips if you have ToString() or DebuggerDisplay enabled. You just see a mangled GUID. Not very helpful.
  • As Ithaqua says, encourages your DB objects to spread throughout your system.
  • It doesn't handle very well partial updates to previously detached object graphs (i.e. come out of the DB, gone across the wire, been modified and sent back)

If you're in a read heavy scenario, EF is definitely not the way to go, and if you're in a write heavy scenario, it also isn't the way to go. It has it's place in CRUD apps.

I don't mean to rubbish EF. Clearly a lot of work and effort has gone into it. But I think it's best suited for low throughput CRUD apps which run in a WPF app, or if everyone on your team is truly awful at SQL.

The idea behind code-first generation stuff also rubs me the wrong way. Design your schema first, then write code, not the other way around.

mobby_6kl
Aug 9, 2009

by Fluffdaddy
I guess I'm in luck because for shits and giggles I decided to "update" my simple CRUD app by rewriting it with EF, Linq and WPF without having much prior experience with either. It went about as well as expected, but I figured most stuff out eventually. However, a couple of things are still giving me trouble.

1. I have a window opened from main that lets the user select which record to edit. There are a couple of filters but the selection is done by choosing from a list view. How can I determine which object was selected in order to tell the controls on my main window what to do?

2. I have a following schema:
SQL code:
table People (P_ID int identity)

table Pets (P_ID *fk, A_ID *fk, A_Name)
primary key (P_ID, A_ID)

table Animals (A_ID, A_Type)
Animals are outside the scope of my app and can't be edited. However, let's say each person can only have at most one animal of each type, hence the PK.

The way I saw this working at first was using an outer join to generate a list of possible animals with checkboxes that the user could check and provide a name:
pre:
[x] Cat  [Fluffy    ]
[ ] Rat  [          ]
[x] Dog  [Rex       ]
However I still have no idea how to make this work. Would it be too much of a pain in the rear end with EF and linq? A simpler solution would be to just have an extra combobox with possible animals and an add button, but I think this list in an Expander would be preferable for the UX point of view.

Edit: cleaned up pseudo-sql

mobby_6kl fucked around with this message at 21:29 on Feb 28, 2014

Milotic
Mar 4, 2009

9CL apologist
Slippery Tilde
Is this using SQL Server? Is that schema fixed? You can use unique constraints on indexed views to enforce those types of constraints (see here. You'd then have a PersonAnimal join table with person and animal, and create a indexed view on that with person and animal type id and with a unique constraint that gets violated if a row was to be inserted into PersonAnimal such that a person would then have two animals of the same type. Alternatively, you could use a multiple table CHECK CONSTRAINT (see here)

Worth mentioning in either case performance will decrease, the first because the insertion execution plan gets a bit horrible, the second because UDFs don't always have amazing performance characteristics. It's a constraint that does feel somewhat artificial though.

Alternative is to have a join table from Person to Animal, and in that join table include the animal type of the animal (yuck), and create a unique nonclustered index on that.

I'd be tempted to do the join in code. Pull back one list of people, one list of animals. Don't do a cross outer join, but if you did the LINQ would probably be:

code:
var combos = (from x in aSet
from y in bSet
select new {x, y}).ToList()

Milotic fucked around with this message at 21:50 on Feb 28, 2014

mobby_6kl
Aug 9, 2009

by Fluffdaddy
Yes, SQL Server is the back end. The schema could be adjusted if there's a good enough reason, but I'm not sure what's the issue with the current setup, as the composite PK constrain would be violated when inserting the second Dog :). Performance isn't critical as the insert volume will be very low.

My main challenge here was turning the schema into a representation as sketched with ASCII-UI. This is a bit silly, but imagine this if clicking the first column created a record in the pets table linking the currently edited person (123) to the appropriate Animal:
SQL code:
select 
   case when Animals.A_ID is null then 'O' else 'X' 
   ,Animals.A_Type
   ,Pets.Pet_Name
from Pets
left join Animals on Pets.A_ID = Animals.A_ID
where pets.P_ID = 123
However your suggestion with the linq join is probably in the right direction and I'll try to make something like that work.

Milotic
Mar 4, 2009

9CL apologist
Slippery Tilde
I tend to favour artificial primary keys over composite myself, which is why I went down the route I suggested. I tend to use composite primary keys only if the schema has stabilised and performance tuning shows major wins by going down that route. Also I had gotten it into my head that Animal represented individual animals rather than types of animal. Considering the trade offs, your Pets quasi-join table + metadata is the best option, though you might want to hang a FK off it pointing to a table with more metadata on the pet. The join table should have the minimum amount of information to enfore any constraint - either via a PK, or a unique nonclustered index (which is actually a constraint).

Destroyenator
Dec 27, 2004

Don't ask me lady, I live in beer
Has anyone used F# type providers? I'm having a play around with a simple F# MVC app and it looks like it's the preferred method for doing database interactions?

From what I understand it queries your db at compile time (including intellisense checking) to determine what types you have in there. It seems kinda cool but I'm wondering if anyone has used it in a regular development workflow?

For example does this mean that the CI build agents all need access to a database? What if I have my db migrations in code (FluentMigrator, or DbUp or something)? They have to build and deploy before building the code containing type providers is built? (On per build db instances?)

All the sample code I can find is pretty basic "you have this simple existing db and you just access fields on it", not much "this is how we use this in the real world".

chippy
Aug 16, 2006

OK I DON'T GET IT
Can anyone point me towards a way of getting property display names by way of using a lambda? I'm going round in circles trying to research this.

Basically I'm looking for a static method so I can go GetDisplayName(someObject => someObject.someProperty) and get a string back. Really this needs to be able to work with the DisplayName and Display(Name=) attributes.

I figure this should be relatively easy but this is not a Monday Morning Problem as far as I'm concerned and it's making my head hurt.

Funking Giblet
Jun 28, 2004

Jiglightful!
It already exists (DisplayNameFor), but if you need it without a helper, the below should show you what is involved in extracting it.

http://stackoverflow.com/questions/3885796/get-displayname-attribute-without-using-labelfor-helper-in-asp-net-mvc

chippy
Aug 16, 2006

OK I DON'T GET IT
Yeah that's right, I want to get it independently of the HTML Helper/View related stuff. I'll have a look at that link though, thanks.

User0015
Nov 24, 2007

Please don't talk about your sexuality unless it serves the ~narrative~!
Been messing with Selenium/SpecFlow recently and I figured I'd ask you guys if there's any way of compiling tests into executable format to run later. Essentially, a nice suite of UI tests that can be kicked off on a virtual machine somewhere that will report failures that doesn't need to have Visual Studio set up.

chippy
Aug 16, 2006

OK I DON'T GET IT
Anyone know how I can convert/cast an
code:
Expression<Func<T, string>>
to an
code:
Expression<Func<T, object>>
?

Edit: Never mind, worked this out.

code:
Expression<Func<TModel, object>> newPropertyExpression = Expression.Lambda<Func<TModel, object>>(emptyStringCheck.Body, emptyStringCheck.Parameters);

chippy fucked around with this message at 10:31 on Mar 4, 2014

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe
Having a strange issue with running a little application at launch once per day. What I'm asking it to do is check for a response from a website (in this case APOD) and then if it gets the response, download an image off the page and save it to the application directory and set the desktop wallpaper to that image. It actually works really smoothly so far, save for a little strangeness. To get it to launch at startup I'm using the registry, specifically "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run".

When it runs at startup, it doesn't save the image where it's supposed to or write a text file I've asked it to write, but it does successfully make the new image from APOD the desktop wallpaper. I threw in a couple lines of logging to make sure the application was working from the right directory and got this in a log.txt file successfully today on boot:


Cycle number: 0
Writing test.txt to Z:\Users\Tim\Desktop\APOD to Desktop\
Saving to apod_3_4_2014.jpg in directory Z:\Users\Tim\Desktop\APOD to Desktop\
New wallpaper set.


Great! But when I open the folder, the image file isn't there and the test.txt file hasn't been modified since yesterday. If I run the application again by double clicking the exe myself, then it does save the jpg properly and modify the test.txt file. I'm just confused why it isn't doing it properly at startup.

Some relevant code snippets:

code:
	    Console.WriteLine("Writing test.txt to " + AppDomain.CurrentDomain.BaseDirectory.ToString());
            using (StreamWriter writer = new StreamWriter("test.txt"))
            {
                writer.Write(htmlCode);
            }

            using (StreamReader reader = new StreamReader("test.txt"))
            {
                String line = String.Empty;
                while ((line = reader.ReadLine()) != null)
                {
                    if (line.Contains("<a href=\"image"))
                    {
                        char[] charsToTrim = { '"', '>' };
                        line = line.Remove(0, 9);
                        line = line.TrimEnd(charsToTrim);
                        line = "http://apod.nasa.gov/apod/" + line;
                        GetApodImage(line);
                        break;
                    }
                }
            }
code:
        public static void GetApodImage(string url)
        {
            using (WebClient Client = new WebClient())
            {
                // Put todays date into the image filename.
                DateTime today = DateTime.Today;
                Console.WriteLine("Saving to " + "apod_" + today.ToString("d").Replace("/", "_") + ".jpg in directory " + AppDomain.CurrentDomain.BaseDirectory.ToString());
                Client.DownloadFile(url, "apod_" + today.ToString("d").Replace("/", "_") + ".jpg");
            }
        }
Any ideas as to why it wouldn't save the txt file or jpg on startup but will if I manually run the exact same executable?

gariig
Dec 31, 2004
Beaten into submission by my fiance
Pillbug
Check the Event Log to see if you have any unhandled exceptions? Do you have any exception handling? I'd guess you are trying to get to the Internet before you have network access and getting an exception. It's hard to debug without seeing the whole application and why certain parts of your log file are the values that they say.

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

gariig posted:

Check the Event Log to see if you have any unhandled exceptions? Do you have any exception handling? I'd guess you are trying to get to the Internet before you have network access and getting an exception. It's hard to debug without seeing the whole application and why certain parts of your log file are the values that they say.

That's the rub though, it definitely has Internet access because it does set the desktop to the new image properly and it does write the log.txt file but not the test.txt or the .jpg file. Right now the coding is pretty rough as I've been brute forcing things in ways that are probably inefficient. I've thrown it up onto Git here, with the three main files being Program.cs, GetApod.cs (used to get the APOD image), and DesktopManager.cs (used to set the desktop style / update the desktop image).

Lots of this is placeholder or piecemeal that I've slapped together to be functional if messy and feedback is welcome, but my main curiosity is why it's not completing steps it obviously passes through and completes somehow on startup but not when running manually. Is it possible the program is exiting before some of the steps are done (basically are downloading files / writing the files to the disk in C# / .NET done in such a way as to not make the program wait for completion before moving to the next line of code?

e: Hmmm. It is properly saving the image to one location: "C:\Users\Tim\AppData\Roaming\Microsoft\Windows\Themes" does successfully have "apod_3_4_2014.bmp" which is being created in DesktopManager, but that bit of code is called after GetApod.GetApodImage (which creates the .jpg file) is called.

Mo_Steel fucked around with this message at 21:26 on Mar 4, 2014

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Mo_Steel posted:

That's the rub though, it definitely has Internet access because it does set the desktop to the new image properly and it does write the log.txt file but not the test.txt or the .jpg file. Right now the coding is pretty rough as I've been brute forcing things in ways that are probably inefficient. I've thrown it up onto Git here, with the three main files being Program.cs, GetApod.cs (used to get the APOD image), and DesktopManager.cs (used to set the desktop style / update the desktop image).

Lots of this is placeholder or piecemeal that I've slapped together to be functional if messy and feedback is welcome, but my main curiosity is why it's not completing steps it obviously passes through and completes somehow on startup but not when running manually. Is it possible the program is exiting before some of the steps are done (basically are downloading files / writing the files to the disk in C# / .NET done in such a way as to not make the program wait for completion before moving to the next line of code?

What account is it running under when you have it execute on startup? What folder is AppDomain.CurrentDomain.BaseDirectory for that account?

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

Ithaqua posted:

What account is it running under when you have it execute on startup? What folder is AppDomain.CurrentDomain.BaseDirectory for that account?

It's running under my user account which is the only one on this sytem, Tim.
AppDomain.CurrentDomain.BaseDirectory properly returns the folder the application is running from: Z:\Users\Tim\Desktop\APOD to Desktop\
The registry key to run it also points to that same folder:



Located in "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run".

gariig
Dec 31, 2004
Beaten into submission by my fiance
Pillbug
I think there are a couple of problems. One you should be fully qualify your paths for files. The reason is you have a bug where you assume AppDomain.CurrentDomain.BaseDirectory is the working directory. That is true if you run it but I'm guessing Windows is spawning your application through another executable. What you want is Environment.CurrentDirectory.

For ending up in the virtual store I'm going to guess it's a trust issue and not strictly a permissions issue. You should be able to write to your Desktop but I'm ending up in %userprofile%\AppData\Local\VirtualStore\Windows\SysWOW64. Being in the VirtualStore means Windows thinks you are doing a no-no. However, I don't know why.

some kinda jackal
Feb 25, 2003

 
 
Have any of you guys adapted to Test Driven development? I'm trying to make myself use NUnit but every time I just think... "why?"

I guess maybe I'm not writing complex enough classes or I'm just missing the bigger picture here.

Sedro
Dec 31, 2008

Martytoof posted:

Have any of you guys adapted to Test Driven development? I'm trying to make myself use NUnit but every time I just think... "why?"

I guess maybe I'm not writing complex enough classes or I'm just missing the bigger picture here.
It sounds like you're opposed to unit testing in general rather than TDD. Unit tests keep existing features working as software evolves. When you add a new feature, do you test every existing feature and every bug that has ever been reported? You can.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Martytoof posted:

Have any of you guys adapted to Test Driven development? I'm trying to make myself use NUnit but every time I just think... "why?"

I guess maybe I'm not writing complex enough classes or I'm just missing the bigger picture here.

I do TDD most of the time now. I don't test drive everything, but any method that returns a value or mutates the state of an object gets tests written before the code. It makes you really think about what your methods are supposed to do... What happens if you pass a null value in? What should happen? What exceptions should this method be throwing, and under what circumstances? The "living documentation" aspect is pretty great, too. I name all my tests along these lines:

code:
[TestClass]
public class When_Fooing_A_Bar
{
    [TestMethod] public void Should_Return_Baz_When_Bar_Is_Null() {}
    [TestMethod] public void Should_Return_Butts_When_Bar_Is_Successful() {} 
    //etc
     
}
Anyone who looks at the code later on immediately sees what the code is supposed to be doing and that it's successfully doing so. It's beautiful.

I'm no longer dogmatic about TDD -- if you're writing a controller or viewmodel that has the bulk of its logic delegated to other classes, there's not much value in testing it.

Like, why bother testing this method?
code:
public ActionResult Foo(SomeViewModel postData) 
{
    var result = someInstance.ProcessSomeViewModel(postData);
    return View(result);
}
If the controller starts to do more, then yes, test it. But don't test it just to chase after 100% code coverage.

Cervix-A-Lot
Sep 29, 2006
Cheeeeesy
So I'm creating this website where users can search a catalog via ajax and get results. I'm having a few issues with saving the search results.

So say someone searches, 'PC54' and clicks on one of the results and goes to the product pages then hits the back button. What would be the best way to save the search they performed?

Session variables?

Mo_Steel
Mar 7, 2008

Let's Clock Into The Sunset Together

Fun Shoe

gariig posted:

I think there are a couple of problems. One you should be fully qualify your paths for files. The reason is you have a bug where you assume AppDomain.CurrentDomain.BaseDirectory is the working directory. That is true if you run it but I'm guessing Windows is spawning your application through another executable. What you want is Environment.CurrentDirectory.

For ending up in the virtual store I'm going to guess it's a trust issue and not strictly a permissions issue. You should be able to write to your Desktop but I'm ending up in %userprofile%\AppData\Local\VirtualStore\Windows\SysWOW64. Being in the VirtualStore means Windows thinks you are doing a no-no. However, I don't know why.

Huh yeah I'm getting the files there too. Alright, thanks, I'll look into it, maybe it's running too early and I should force a minute or two delay off the bat to let other Windows processes sort themselves out first.

gariig
Dec 31, 2004
Beaten into submission by my fiance
Pillbug

Mo_Steel posted:

Huh yeah I'm getting the files there too. Alright, thanks, I'll look into it, maybe it's running too early and I should force a minute or two delay off the bat to let other Windows processes sort themselves out first.

I'd use the Task Scheduler and force it to run as your user. I'm guessing whatever starts the processes in the registry runs at a lower trust level so malware can't slip in and keep autorunning. At least that is what I would do.

RangerAce
Feb 25, 2014

Martytoof posted:

Have any of you guys adapted to Test Driven development? I'm trying to make myself use NUnit but every time I just think... "why?"

I guess maybe I'm not writing complex enough classes or I'm just missing the bigger picture here.

The biggest benefit of TDD is that when working with other programmers on the same codebase, you can write tests to ensure that when other team members say "it's done," that it actually is done.

Now imagine that the other programmer is someone who will work on your codebase 6-12 months from now. TDD will help you ensure that methods you write now will continue performing as intended in the future. That other programmer is you. When you dig back into code and decide to change what the one little method does, you can save yourself from unintended consequences of those changes because you had a unit test that covered that.

In my mind, unit tests are a way of codifying what you expect your code to do.

RICHUNCLEPENNYBAGS
Dec 21, 2010
I think unit tests can be valuable, but I'm a little bit annoyed when I see people talking about them because people pretend (or actually believe? Which is worse) that tests guarantee code is bug-free. That's only true if you anticipated the conditions that cause the bug to occur and I have experienced cases where that wasn't happened.

I personally prefer tests after writing the code, though, rather than TDD, because I find I change my mind a couple times as I'm working through on what exactly I want it to look like and having tests already writen makes me more likely to press on instead of making it better.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

RICHUNCLEPENNYBAGS posted:

I personally prefer tests after writing the code, though, rather than TDD, because I find I change my mind a couple times as I'm working through on what exactly I want it to look like and having tests already writen makes me more likely to press on instead of making it better.

Are you sure you're doing TDD, then? Write one test, make that test pass, refactor, repeat. You don't sit down and write out 30 tests then start coding to those tests. It's an iterative process that explicitly tells you to refactor as you go. Like I said, I feel like it really makes you think harder about what your code is doing.

It also cuts down on trying to code to every imaginable possibility. You ask yourself, "What does my code need to be doing today so that I can close out this task?", and then you do that.

Does it guarantee your code is bug-free? Of course not. It doesn't even guarantee that you didn't break any existing functionality. But it helps, sometimes a lot. I've been saved from doing dumb things by unit tests so many times now.

rebelEpik
Jun 9, 2012
Seeing as the OP was last updated in 2009, I was wondering if anyone had any great starter books for learning C# that they could recommend?

Smugdog Millionaire
Sep 14, 2002

8) Blame Icefrog
I've found what I believe to be a C# compiler bug. http://dotnetpad.net/ViewPaste/kAolYQIdgk-TyOFVjZvpbA

What I'm doing (to my understanding) is creating boolean values that aren't 0x00 or 0x01. The C# compiler clearly generates bitwise comparisons under the expectation that bools outside that range will not or cannot exist. However, I can't find a justification for this assumption. Booleans are a type that's built into the CLR, and my understanding of that specification is that any non-zero value is a valid 'true' value.

Here's what ECMA-335 says about bools:
  • "A CLI Boolean type occupies 1 byte in memory. A bit pattern of all zeroes denotes a value of false. A bit pattern with any one or more bits set (analogous to a non-zero integer) denotes a value of true." (pg 293)
  • "4-byte integer value where any non-zero value represents TRUE, and 0 represents FALSE." (this section is actually about how bools should be marshalled, pg 125)
Here's what the C# language specification says about bools:
  • "C#’s bool type is used to represent boolean values—values that are either true or false" (pg 4).
  • "The members of bool are the members of the System.Boolean struct" (pg 59).
  • "The bool type represents boolean logical quantities. The possible values of type bool are true and false." (pg 83)
Here's what the C# language specification says about the operators:
  • "The result of x == y is true if both x and y are true or if both x and y are false. Otherwise, the result is false. The result of x != y is false if both x and y are true or if both x and y are false. Otherwise, the result is true. When the operands are of type bool, the != operator produces the same result as the ^ operator." (pg 201)
  • "The result of x & y is true if both x and y are true. Otherwise, the result is false. The result of x | y is true if either x or y is true. Otherwise, the result is false." (pg 206)

So, bools are either true or false, and any non-zero value is true. I couldn't find any language like "oh but all bets are off if the booleans aren't 0 or 1". If my understanding is correct, this is a bug in the C# compiler. A bug that won't affect anyone, probably. At least until I develop my own CLS-compliant language that does create and use boolean values outside of zero and one. Am I wrong?

gariig
Dec 31, 2004
Beaten into submission by my fiance
Pillbug

rebelEpik posted:

Seeing as the OP was last updated in 2009, I was wondering if anyone had any great starter books for learning C# that they could recommend?

Microsoft C# Step-by-Step looks pretty good and there are some good reviews. I've always been fond of the Head First series and there is a HeadFirst C#. The one thing about the Head First is that it gets you into Windows Store 8 applications (WPF) and ASP.NET. You'll probably still need another book to learn either of those technologies.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

I don't know enough about the CLI or C# specifications to speak to what you described, however I would really like to know how you got around to discovering this.


EDIT: Ohh, now I see what is happening:

true = 0x01
false = 0x00
if (boolean)
is equivalent to if ((byte)boolean > 0)
boolean1 == boolean2
is comparing the byte representation

This illustrates that pretty well: http://dotnetfiddle.net/5epddO

Bognar fucked around with this message at 15:28 on Mar 6, 2014

Smugdog Millionaire
Sep 14, 2002

8) Blame Icefrog

Bognar posted:

I don't know enough about the CLI or C# specifications to speak to what you described, however I would really like to know how you got around to discovering this.

A few years ago, I saw a few people in CoC posting about unexpected C++ behavior and they would cite the language specification to explain what was really going on. Nerds love/respect people that have a mastery of the arcane, so I thought I'd read the C# language specification and be the same sort of language wizard. The C# language specification wound up being kind of boring, turns out almost everything is totally straightforward (the hallmark of good language design, perhaps). So I kept digging and read (some of) the CLI specification, which is how I found out that bools are really 8 bit integers under the hood.

For some reason I looked up the "bitwise" operators & | ^ on MSDN which said that when applied to booleans, those operators perform the logical operations. I had always assumed they just did bitwise and/or/xor, which doesn't give you the correct behavior if booleans can exist outside the range of 0 and 1. I decided to test it, and there you go.

RICHUNCLEPENNYBAGS
Dec 21, 2010
What do you guys do for logging?

My former boss did all the logging stuff in the application I'm working on. It's using log4net and there are a bunch of custom exception types that inherit from a "logging exception." So what he's doing is putting try-catch blocks everywhere, then in the catch block he puts the exception in the inner exception of one of these custom exceptions with logging, then throws.

To be honest, I hate this approach because I think it's really messy. In my ideal world I could just annotate classes with an attribute like [LogExceptions], but I'm sure there are other ways to do this without littering the entire application with logging-related junk.

ljw1004
Jan 18, 2005

rum

Smugdog Millionaire posted:

I've found what I believe to be a C# compiler bug. http://dotnetpad.net/ViewPaste/kAolYQIdgk-TyOFVjZvpbA
What I'm doing (to my understanding) is creating boolean values that aren't 0x00 or 0x01.

That's a nice find!

You might say that the normal behavior of [StructLayout/FieldOffset] itself is a bug, because there's NOTHING in the language spec that explains why even a program with these attributes used for aliasing behaves the way it does. That's why the C# language designers are generally opposed to behavior-modifying attributes :)

Stated more strongly, these attributes are one of the backdoors to get something that's not achievable or explainable in the pure C# language. There are lot of other backdoors - e.g. importing metadata from C++/CLI that uses "protected AND internal" accessibility, or importing metadata with names that aren't legal in C#, or marshalling, or using CLR to construct an object without invoking its constructor (as used in DataContract), or reflection.

Since the language spec doesn't explain what should happen when you go through one of these backdoors, it's hard to say that the compiler's behavior is in violation of the spec, and hence hard to call the compiler's behavior a "bug" as such...

Opulent Ceremony
Feb 22, 2012

RICHUNCLEPENNYBAGS posted:

What do you guys do for logging?

My former boss did all the logging stuff in the application I'm working on. It's using log4net and there are a bunch of custom exception types that inherit from a "logging exception." So what he's doing is putting try-catch blocks everywhere, then in the catch block he puts the exception in the inner exception of one of these custom exceptions with logging, then throws.

To be honest, I hate this approach because I think it's really messy. In my ideal world I could just annotate classes with an attribute like [LogExceptions], but I'm sure there are other ways to do this without littering the entire application with logging-related junk.



We use Elmah, the lazy person's logging library. You just configure it and it will log your application's exceptions with virtually no logging-specific code in your app code at all if you don't want.

subx
Jan 12, 2003

If we hit that bullseye, the rest of the dominoes should fall like a house of cards. Checkmate.
I was wanting to build something that would take a linq IQueryable object and a list of string "properties" and do something with each result that outputs the matching properties. (Ultimately this is going to output to Excel)

I can't figure out how to make it work properly. I haven't done a whole lot with Linq and reflection.

Code:

code:
var query = context.SomeTableOrSP();
var properties = new List<string>(new string[] "name", "documents", "totals")

CreateExcelFile(query, properties);

public static Stream CreateExcelFile(Iqueryable query, List<string> properties)
{
	foreach(var item in results)
	{
	// snip, some stuff to build excel rows and columns

		foreach (var prop in properties)
		{
			// This is where I'm not sure how to go about getting the value
			object cellValue = GetValue(item, prop);  

			// snip, some stuff to build excel rows and columns
		}
	}
}
Any help is appreciated.

RichardA
Sep 1, 2006
.
Dinosaur Gum
To get the property from the name the following works.
code:
public static object GetValue(object src, string propName) {
    return src.GetType().GetProperty(propName).GetValue(src, null);
}
Edit: In most cases. If it is ambiguous you may need to use a different overload of GetProperty. Unless you are using indexers or and a derived class is hiding a property with new you should be fine.

RichardA fucked around with this message at 23:32 on Mar 6, 2014

Adbot
ADBOT LOVES YOU

RICHUNCLEPENNYBAGS
Dec 21, 2010

Opulent Ceremony posted:

We use Elmah, the lazy person's logging library. You just configure it and it will log your application's exceptions with virtually no logging-specific code in your app code at all if you don't want.
Wow, that's great. It's pretty much what we're doing now, except making a big hash of the code because of it.

  • Locked thread