No. The price of a microcontroller running the .NET framework will always be greater than the price for a microcontroller with equivalent performance (or equivalent to the price of a micro with greater performance) which is programmed in assembly, C, or even using the Arduino tools.
When buying a microcontroller for the .NET framework, you pay for small transistors, you pay for more transistors, you pay for complexity, you probably pay for licensing a core developed somewhere else, and, since you're paying for all that, most manufacturers imagine that you'll want to pay for higher pin-count packages since your die budget supports them. If you did this in assembly or C, you could get equivalent performance and pay a lot less.
See also the following questions:
The first question in the list is very applicable to this question, it just discusses the suitability of the .NET micro framework as opposed to the pricing and programming which we're discussing here.
If you still want to use .NET, you think you can get acceptable performance out and you're going to be buying a significant number of parts (at least 1k, probably easier at 10k), you can do the same thing that the vendors of the FEZ parts do: Have it loaded at the factory. It costs somewhere in the region of a quarter apiece to program large files like the one you'll be working with.
Although the PIC18F4550 is a decent uC and there are quite a few examples out there of using it for USB, it's still 8-bit and probably in the same "league" as your Arduino.
If you want a bit more power, I would maybe look at the 16-bit PIC24/dsPIC (a lot more powerful and still available in through hole) or even the PIC32 (surface mount only though, and you would generally use C to program it)
I thought the PicKit3 (I assume you are referring to this) was not too bad price wise as programmers go, but if you want cheaper you could go for the PicKit2, which although not officially supported anymore, will still be usable with 99% of Microchips range.
There are also many other decent programmers for PICs, for example the Embed Inc offerings - if you go for the 16-bit 3.3V parts I imagine the $25 LProg would be suitable.
Although online resources and a good related book (e.g. Learning to Fly the PIC24 - note this is C based) makes getting started easier, I would get used to reading the datasheets (and Family Reference Manual in the case of the PIC24/dsPIC) thoroughly, it is a necessary part of using any microcontroller and the only way (IMHO) to learn how to use them fully, especially the more complicated ones. Even the above book (though well written) misses out a lot of lower level detail.
Best Answer
That PIC uses the basic 14 bit core, so there are only two special locations in program memory, 0 and 4. Execution starts at 0 after reset, and a call is performed to 4 on interrupt. You have to make sure the very first instruction of your code gets put into location 0. If you are using interrupts, you have to make sure the first instruction of the interrupt routine is placed in location 4.
Most of the time you want to not specify where code goes to give the linker the most flexibility in placing sections of code. This is done by using the CODE directive without any arguments. To force code to get placed into a particular location, you preceed it with a CODE directive followed by the fixed address. This tells the linker it has to go right there and nowhere else. The linker will issue a error message if that is not possible for some reason.
The simple thing is to place the start of the first module at 0, then let the linker place the others as it sees fit. However, most projects use interrupts, so the code at zero can't run over the interrupt vector at 4. As a result, you usually have the code at 0 jump to code in another segment that is relocatable, while making sure the fixed code at 0 is no more than 4 instructions long.
Here is general startup code for this processor core:
Note the 0 behind the first CODE directive. That forces the following code to start at location 0. Since there are 4 instructions available, you can do just a little stuff other than jumping to the relocatable startup code. In this case, I make sure all interrupts are off. Interrupts will be off when getting here due to a hardware reset, but it can be useful to have the code at 0 also work if jumped to at any time from the middle of application code. Some of the other cores have a RESET instruction for that purpose, but this core does not.
The next two lines perform a jump to any location in the full program memory address space. Since the jump is to fully relocatable code, there is no guarantee where it might end up getting placed by the linker. The GOTO instruction only contains the low 11 bits of the 13 bit program memory address, with the remaining bits coming from PCLATH. The PAGESEL directive sets these bits appropriately for the code page that START happens to be on.
This particular PIC only has one code page of program memory, and PCLATH is cleared on reset. In this particular case, you don't need to load PCLATH, but it's a good idea anyway. First, you have 4 instructions available for the fixed startup code. Not using PAGESEL would take two instructions less, but those instruction locations will be difficult to utilize otherwise anyway. Second, this is the kind of detail easily forgotten when the code is moved to a newer PIC with more memory.
Actually I use macros for this that are smart enough to know whether the machine has only one code page or more than one code page and emit the extra bank setting instructions in the second case. I am showing a simpler but totally robust version of the startup code here.
The second CODE directive starts a new linker section, but this time no address is specified. That makes the linker section relocatable, meaning the linker is allowed to place it where it sees fit. The code following the second CODE directive can end up anywhere in memory, and on larger PICs might not be in page 0.
The interrupt service routine is started similarly, with a "CODE 4" directive. However, since there are no other special fixed locations following 4, the interrupt routine can go there directly. Some code will end up following location 4, so it might as well be the only routine that actually benefits from being there. In other words, unlike with the startup code, don't split the interrupt code into fixed and relocatable sections. Put the whole thing in a fixed section starting at 4.
Added about interrupt vector
There is significant bad information out there about the best use of the interrupt vector on a 14 bit core part like the one asked about. Even Microchip is guilty of propagating some of this. Let's debunk some of the nonsense:
Without knowing the specifics of particular projects, the interrupt routine is likely the most timing sensitive. A GOTO takes two extra cycles for absolutely no benefit. It's not like you're making a tradeoff here to get something else.
This is just a religious knee-jerk "rule of thumb".
To jump to some arbitrary location in program memory therefore requires setting these two bits of PCLATH properly before the GOTO. But, you need the interrupt routine to preserve PCLATH. That means PCLATH needs to be saved somewhere first. However, it takes W to do that. That means W has to be saved before PCLATH can be saved. Depending on how you save these, STATUS may also have to be saved first since some of these operations can alter the status bits.
This particular question was about the 12F683, which happens to only have one page of program memory. In this specific case, you could use the convention that the page bits in PCLATH are always kept cleared, and that the interrupt routine therefore does not need to set them. A GOTO at 4 would therefore work in this specific case, but only because this PIC doesn't have multiple pages of program memory. Doing that is still bad practise because this restriction built into the interrupt routine will be easily unnoticed if the code is ever moved to a PIC with more program memory.
So what's the right way? Here is the code I actually use on the basic 14 bit core:
W is saved first, and W_SAVE must be in unbanked memory or replicated at the same offset in every bank. SWAPF is used to grab STATUS. This allows STATUS to be restored later (see below) without corrupting some of the status bits. STATUS is then cleared, which is the simplest way to set the two bank bits to a known state. Then STATUS is saved to STATUS_SAVE, which can now be at a single location in bank 0.
DBANKIS and IBANKIS are macros that are part of my system of managing the bank setting at build time. These two macros emit no code, but tell the build-time system that the direct and indirect bank settings are both 0.
Note that PCLATH is conditionally saved. My system maintains the NCODPAGES assembler constant for the target PIC to be the number of code pages that particular processor has. PCLATH is only saved if the machine has more than one code page. In the case of the 16F683, NCODPAGES is 1 and these instruction would not be included. However, if the code is ever moved to the next size up PIC, then NCODPAGES would be larger and PCLATH would be saved and restored by the interrupt routine. Note that in that case PCLATH not only needs to be saved, but also set to page 0 so that local GOTOs within the interrupt routine go to the correct page.
The code to return from the interrupt routine is:
Now it can be seen why the nibbles of STATUS were swapped earlier, which is so SWAPF can be used to read the saved byte into W. Unlike MOVF, SWAPF changes no status bits.