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
Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
What kind of deployment process are you using? Are you using an installer project?

The build settings are project dependent, so if you've set your main project to build in 4.0 your installer project could still be set to 4.5.

If you're using ClickOnce deployment there might be some extra options you can set to target 4.0, but I haven't used ClickOnce in years so I don't know.

Adbot
ADBOT LOVES YOU

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
This link might be useful:

http://stackoverflow.com/a/12181324/957673

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Design View has been a never-ending source of problems for me, regardless of whether I'm in ASP.NET, WinForms, or WPF. I gave up on it long ago and just edit code + debug to see what something will look like.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Sab669 posted:

Determined that the error is occurring in a .net call to System.Management.ThreadDispatch.Start()

The software works on other computers, just this 1 machine.


Potentially related? http://stackoverflow.com/questions/7165174/system-management-managementexception-not-found

It's not the same error, but it's the same package. Maybe you could try running through the steps to repair WMI. That might help since the problem is isolated to this one machine and is likely a configuration issue somewhere.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
I've always just used raw XML or the OOXML API to deal with Word. It's a good bit more to load into your head, but it gives you a ton of power for dealing with documents. This is a pretty good article on using XML for Word: http://msdn.microsoft.com/en-us/magazine/cc164064.aspx

EDIT: Optionally, you could try out DocX.

http://docx.codeplex.com/
http://cathalscorner.blogspot.com/2010/06/cathal-why-did-you-create-docx.html

Bognar fucked around with this message at 16:18 on Aug 12, 2013

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

dotalchemy posted:

...Active Directory...



I would just cast p as a UserPrincipal and call GetGroups.

C# code:
...
    foreach (Principal p in grp.GetMembers(true))
    {
        Console.WriteLine(p.Name);

        var user = p as UserPrincipal;
        if (user == null) continue;

        var groups = user.GetGroups();
        foreach(var group in groups)
        {
            //DoSomething();
        }
    }

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
If you have the project referenced but aren't able to find the right "using" statement, try pressing Alt+Shift+F10 on the method you're trying to find the reference for.

Optionally, pony up for ReSharper.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Sab669 posted:

I sent the project to my coworker and he could see it just fine :psyduck:
I ended up just restarting VS / cleaning & rebuilding the solution and it was all set... The weirdest...

I've gotten into some bizarre situations that were fixed (or broken) by a clean and rebuild.

My favorite was when a coworker managed to generate a circular reference after some refactoring. He had a project that referenced another project, but then he moved some pieces from one project into another and changed the reference direction. Well, the project that initially had the reference didn't ever rebuild for some reason, but Visual Studio still let him add a reference in the other direction on the other project. It would build fine on his machine, but it broke the build of everyone else who pulled it down from source control. After a clean/rebuild, his machine finally told him that it was screwed up.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Yeah, these days it's much harder to packet sniff MMOs because they've started encrypting all of their traffic. Gone are the days of sending your own spell damage packets to the EQ servers.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
I learned Entity Framework from the MVC tutorials online. I strongly suggest not learning EF that way - it leads to very tightly coupled code if you follow their examples.

This book comes highly recommended, but it was originally for EF4 while the current version is EF5 (soon to be 6) and I don't know if it's been updated: http://www.amazon.com/dp/1449312942/

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

epalm posted:

Side question: for complex types with lists and reference objects, I don't see any automatic way to copy the values from dto back to entity. Confirm/deny?

Not by default that I know of, and if there were I wouldn't trust it. If it bothers you having a bunch of (potentially duplicated elsewhere) simple assignments, spend the very small amount of time it takes to write a helper method for your DTO.

epalm posted:

So we finally come to my question: in what situation would you want to move an entity across datacontexts?

I can't think of a good one. I've seen it done in some places to get around lag from having a huge context (e.g. 5000+ objects to track) or for migrating data from one database to another, but in each of those cases it was much better (both for performance and code quality) to replace the EF code entirely with something closer to the database like a stored procedure.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Dietrich posted:

That is one leaky abstraction. His controller needs to know way too much about the requirements of entity framework. Imagine if it just had to call Order ILoadOrder.Execute(int orderId) then bool IUpdateOrder.Execute(Order order), and the query and command objects that implemented these interfaces automatically got a context injected into them that was scoped to the web-request.

I have to agree. He abstracted an ORM so that he could make his own ORM. Also, Entity Framework gives you out of the box change tracking, why would you go back to managing object states on your own? His controller is still doing a shitload of interaction with an ORM which is what I would prefer to be abstracting away.

Also,

code:
ViewBag.Customers = new StaticPagedList<Customer>(
    customers, pageNumber, pageSize, totalCustomerCount);

...

@foreach (var item in ViewBag.Customers)
{
    ...
}
:argh: Don't use ViewBag! This is what ViewModels are for!

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Rocko Bonaparte posted:

What's the convention in VS2012 for using Nuget packages with source control? We're using git and don't want to upload all the binary packages we're using. Is there a way to keep the references to the packages intact so that a new developer can have them acquired without a fuss?

Doesn't NuGet create a packages folder that it stuffs all the necessary files into? Just include that in your version control.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Milotic posted:

I could have used WCF + SOAP, but it's always felt a bit of a ballache to get it working, especially when you need to start configuring it.

I've always felt WCF was one of the quickest and easiest ways to handle IPC in .NET. I'd be glad to be proven wrong, though.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Milotic posted:

Anyone know of a good tool for querying/posting to REST services? Yeah, there's fiddler, but it could probably be better when it comes to posting stuff/auto-suggesting headers as you type.

In Firefox, I use RESTClient. It doesn't have any super amazing features, but it gets the job done for specifying any authentication type, headers, and request body.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
What kind of application is this that you're okay with distributing a connection string but not setting up a web service? If it's all intranet, then really Windows authentication is the way to go. If for some reason you really, really don't want to do that (do it anyway), you should be setting up a web service. I don't know what they mean by "not having the hardware for it", it could drat near be run on the same box as the database if all you need to do is authenticate the connection then pass through to the database. Any other solution is just security through obscurity and not secure at all.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Gnack posted:

code:
public class Competition
{
    ...

    // Navigation properties
    [InverseProperty("Competitions")]
    public ICollection<User> Users { get; set; }
}

public class Role
{
    ...

    // Navigation properties
    [InverseProperty("Roles")]
    public ICollection<User> Users { get; set; }
}

In most cases you shouldn't need the InverseProperty attribute. Entity Framework is smart enough to figure out that you want a many-to-many relationship there. You should only have to use InverseProperty if for some reason the convention isn't picking up your relationship, you want a self-referencing entity, or you want multiple relationships between the same two entities.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

glompix posted:

I've been wondering this: With MVC4 bundling/minification, why even bother keeping preminified files? I've just been deleting my preminified files that show up with NuGet pulls.

The MVC4 bundler should use minified files if it's in release mode and the regular files if it's in debug mode. See http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification "Using Bundling and Minification with ASP.NET MVC" about halfway down the page.

It's my understanding that the MVC4 minifier isn't perfect since it leaves some optimizations out in favor of minification speed (since it has a file system dependency and re-minifies/re-bundles anytime a file changes). So the minified files that show up in NuGet are probably more optimally shrunk. Then again, I'm sure it's a miniscule difference at that point so it might not matter too much.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Uziel posted:

Ugh, requires IE10 to be installed.

IE10 is at least a decent browser. Don't ask me in 7 years when I'm still supporting it, though. I'm assuming they have some kind of special web debugging tool in VS2013 that works with IE10.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Uziel posted:

Edit: OK I had some more coffee and came to my senses. All of the HttpContext stuff was moved out of the model and back into the controller. The model constructor now takes a dictionary now so I'm not passing the HttpContext around.

Good. Your model is for data and your controller is what should be dealing with anything related to web stuff.

EDIT: Wait, are you still setting cookies inside of your view model?

Bognar fucked around with this message at 17:17 on Oct 27, 2013

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
ASP.NET MVC unit testing kind of sucks without first wiring up a DI container. If you get that set up, then you can do something like this:

C# code:
public class ProfileController : Controller 
{
    private readonly IProfileManager _profileManager;

    public ProfileController(IProfileManager profileManager)
    {
        _profileManager = profileManager;
    }

    [HttpGet]
    public ActionResult Index()
    {
        var profileViewModel = new ProfileViewModel(_profileManager.GetProfile());
        return View(profileViewModel);
    }

    [HttpPost]
    public ActionResult Index(ProfileViewModel profile)
    {
        if (!ModelState.IsValid) return View("Error");
        _profileManager.UpdateProfile(profile);
        return RedirectToAction("Index");
    }

    etc....
}

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
I'm always hesitant about giving people access to machines, regardless of whether that's warranted or not. My initial response would be to set up a simple web service/site that serves up the log files when the right person requests them.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Uziel posted:

I understand the code you posted above, I guess I just need to find the easiest/most straight forward/best examples DI method to inject the dependency. Any suggestions as to which to use that will get me up and running quickly? What about Funq, as I'll already be using some features from Service Stack?

For MVC, it's pretty easy to get Unity up and running - just get the Unity.MVC NuGet package. I've never used Funq, nor many other DI containers, so I couldn't really tell you the (dis)advantages of each.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Uziel posted:

Also, my target for this project is mobile only so performance matters.

DI containers affect your server response generation time, which is the least of your worries about mobile. Worry instead about the size of the files you send back and limiting the amount of javascript that runs.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Sab669 posted:

Is there a way, in WinForms / .NET 3.5, to launch the user's default browser and use their default search provider to look something up?

...code...

It seems that different browsers handle the arguments differently :saddowns: (no surprise there though)
I wasn't sure if there was some other way to do this?

I stumbled across this post on SO:
http://stackoverflow.com/questions/16592424/c-sharp-launch-default-browser-with-a-default-search-query
The selected answer works for IE but not Chrome v26 which is what I've got at work and can't upgrade. When I set FireFox to my default browser, FireFox looked for a local file named after the second parameter.

Why not just search Google by default? Build your query string and let windows figure out how to open it.

C# code:
	var query = "https://www.google.com/search?q=" + HttpUtility.UrlEncode(searchString);

	var startInfo = new ProcessStartInfo("explorer.exe", query);
	Process.Start(startInfo);
You want to use ProcessStartInfo with explorer.exe because Windows 8 Metro has screwed up some things with the way processes launch.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Historically, 2D games in Unity were just isometrically rendered 3D games because 2D support was basically nil. Recently, though, the Unity team announced more tooling for actual 2D games so it could be a useful engine for that by now.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
.Distinct() is what you're looking for.

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.distinct%28v=vs.110%29.aspx

Assuming your database access looks something like this:
code:
var blueColors = db.ApparelGroupColors.Where(c => c.Contains("Blue")).ToList();
You could add the .Distinct() method like so:
code:
var blueColors = db.ApparelGroupColors.Where(c => c.Contains("Blue")).Distinct().ToList();
EDIT: Though it seems like there might be an issue with your database design. Why do you have multiple of the same color in the first place? You should consider having a Colors table and the other tables reference that where necessary.

Bognar fucked around with this message at 03:07 on Nov 15, 2013

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Ok, I think I see the problem. If you don't want to show duplicates of the same name, you're going to have to figure out which ones you want to throw out (if you want to include Image or Id). You're counting multiple "Blue" entries as duplicates when they're not really duplicates (Id and Image could be different). One option is to only take the first ApparelProductColor of any particular ColorCode entry that you find, e.g. if there are 10 "Blue" entries you would only return the first one. You can do that with a GROUP BY clause and then take the first of that group.

C# code:
SearchViewModel model = new SearchViewModel()
            {
                MainColorList = (from a in db.GroupColors
                                 orderby a.DisplayOrder
                                 select new GroupColorListViewModel()
                                 {
                                     GroupColorId = a.Id,
                                     GroupColorName = a.Name,
                                     GroupColors =  (from b in
                                                    (
                                                         from b in db.ApparelGroupColors
                                                         where b.GroupColorId == a.Id
                                                         group b by b.ApparelProductColor.ColorCode
                                                         into g
                                                         select g.FirstOrDefault()
                                                    )
                                                    select new GroupColorsViewModel()
                                                    {
                                                        Name = b.ApparelProductColor.ColorCode,
                                                        Image = b.ApparelProductColor.ColorSquareImage

                                                    })
                                 }).AsEnumerable()
            };

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
So I just want to make sure you understand what's going on there, since it's really easy to blindly copy/paste code from the internet until something works.

Let's look at a potential list of ApparelProductColors joined on GroupColors (via ApparelGroupColors).

pre:

GroupColor.Id | GroupColor.Name | ApparelProductColor.Id | ApparelProductColor.ColorCode | ApparelProductColor.ColorSquareImage
-------------------------------------------------------------------------------------------------------------------------------
            1 |            Blue |                      1 |                     Baby Blue |                               1.png
            1 |            Blue |                      2 |                          Blue |                               2.png
            1 |            Blue |                      3 |                          Blue |                               3.png
            1 |            Blue |                      4 |                     Blueberry |                               4.png
            2 |           Black |                      5 |                    .doc Black |                               5.png
            2 |           Black |                      6 |                    .doc Black |                               6.png
            1 |            Blue |                      7 |                          Blue |                               7.png
            1 |            Blue |                      8 |                     Baby Blue |                               8.png
            2 |           Black |                      9 |                         Black |                               9.png
            3 |             Red |                     10 |                           Red |                              10.png
Let's filter to only blue colors (where b.GroupColorId == a.Id):

pre:

GroupColor.Id | GroupColor.Name | ApparelProductColor.Id | ApparelProductColor.ColorCode | ApparelProductColor.ColorSquareImage
-------------------------------------------------------------------------------------------------------------------------------
            1 |            Blue |                      1 |                     Baby Blue |                               1.png
            1 |            Blue |                      2 |                          Blue |                               2.png
            1 |            Blue |                      3 |                          Blue |                               3.png
            1 |            Blue |                      4 |                     Blueberry |                               4.png
            1 |            Blue |                      7 |                          Blue |                               7.png
            1 |            Blue |                      8 |                     Baby Blue |                               8.png
Now let's group by the ColorCode (group b by b.ApparelProductColor.ColorCode):

pre:

**Group Baby Blue**
    GroupColor.Id | GroupColor.Name | ApparelProductColor.Id | ApparelProductColor.ColorCode | ApparelProductColor.ColorSquareImage
    -------------------------------------------------------------------------------------------------------------------------------
                1 |            Blue |                      1 |                     Baby Blue |                               1.png
                1 |            Blue |                      8 |                     Baby Blue |                               8.png

**Group Blue**
    GroupColor.Id | GroupColor.Name | ApparelProductColor.Id | ApparelProductColor.ColorCode | ApparelProductColor.ColorSquareImage
    -------------------------------------------------------------------------------------------------------------------------------
                1 |            Blue |                      2 |                          Blue |                               2.png
                1 |            Blue |                      3 |                          Blue |                               3.png
                1 |            Blue |                      7 |                          Blue |                               7.png

**Group Blueberry**
    GroupColor.Id | GroupColor.Name | ApparelProductColor.Id | ApparelProductColor.ColorCode | ApparelProductColor.ColorSquareImage
    -------------------------------------------------------------------------------------------------------------------------------
                1 |            Blue |                      4 |                     Blueberry |                               4.png
Now we'll take the first from each group (select g.FirstOrDefault()):

pre:

GroupColor.Id | GroupColor.Name | ApparelProductColor.Id | ApparelProductColor.ColorCode | ApparelProductColor.ColorSquareImage
-------------------------------------------------------------------------------------------------------------------------------
            1 |            Blue |                      1 |                     Baby Blue |                               1.png
            1 |            Blue |                      2 |                          Blue |                               2.png
            1 |            Blue |                      4 |                     Blueberry |                               4.png
So we've effectively filtered out any additional duplicate ColorCode entries by only taking the first one of each that appears in the data set.

Bognar fucked around with this message at 05:14 on Nov 15, 2013

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

ManoliIsFat posted:

Can't you just delete the property from your DBcontext? Or create an Empty controller and create your View Model and Views manually.

I'm with this - build your poo poo manually. Inevitably, you'll end up changing the scaffolding and it's really barely useful as it is. Getting used to making the views/methods on your own is a good habit to get into.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
:barf:

You can read your data, but can you read your code?

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Looks like you're not setting bounds.Height and bounds.Width.

C# code:
        BitmapTransform transform = new BitmapTransform(); 
        BitmapBounds bounds = new BitmapBounds(); 
        bounds.X = startPointX; 
        bounds.Y = startPointY; 

        /************************************/
        bounds.Height = height; 
        bounds.Width = width; 
        /************************************/

        transform.Bounds = bounds; 

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

gariig posted:

For ASP.NET there's the website which has lots of learning material.

Be warned - while the code displayed on those websites is useful for learning ASP.NET MVC and Entity Framework, the style is not at all good for building a large production application (e.g. accessing your database directly from your controller, using ViewBag, using your domain models as view models or parameter objects). A new guy started at our office this week and we set him up with the MVC5 tutorials, but we're finding that we have to go back and tell him to unlearn half the things the tutorials suggest.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
They've been planning for a while to change their model for the .NET 4 release to be closed source and paid license. I was planning on using ServiceStack for one of my recently started projects until I saw their pricing model, then I decided heavily against it.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Bluffoon posted:

I had some concerns over the tutorial too (the database access in the controllers, and the ViewBag stuff, since I'd never dealt with it before), so I was planning on getting a working test version up and running with the method suggested in the tutorial, and then going back and refactoring out the database access to use some kind of data access layer (likely the repository pattern). Would that, in your opinion, result in a decent architecture for the application, or is the tutorial so screwed up that it's best to start from scratch? The application is on Azure, and uses an existing database (also on Azure), so I've been following along with the "Database first" parts of the tutorial.

The only issue with that is that you won't be able to unit test your controllers until you refactor out all the database access. The architecture sounds like it would be fine at the end of it, though.

Try to avoid using data models as View models or Action method parameters from the very beginning. That can be a bit harder to refactor after the fact.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Ithaqua posted:

I saw a great presentation by Dustin Campbell from Microsoft last week. He talked about the future of C# and mentioned some cool stuff they have planned for C# 6.

I found a blog post by someone who paid attention at a similar talk and took good notes, which I didn't.

TFA posted:

// monadic null checking
if (points?.FirstOrDefault()?.X ?? -1 )

This is awesome. We've discussed this kind of feature at length in my office, even suggested the exact same signature (I think we called it a "coalescing access operator"). It just gets so annoying to have to write things like:

code:
public bool IsBazzed(Thing thing)
{
    if (thing == null) return false;
    if (thing.Foo == null) return false;
    if (thing.Foo.Bar == null) return false;

    return thing.Foo.Bar.IsBazzed
}
--------------

ShaunO posted:

Can you go into more detail on what you mean by avoiding Action method parameters? Or do you mean don't bind your data model to the action parameters?

Sure. You should avoid your Action method signatures having Models as parameters. Try to stick to primitive types or parameter objects created just for that method (or similar methods). Basically, never do this poo poo (from http://www.asp.net/mvc/tutorials/mvc-5/introduction/examining-the-edit-methods-and-edit-view):

code:
public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")] Movie movie)
{
    if (ModelState.IsValid)
    {
        db.Entry(movie).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(movie);
}
Notice the BindAttribute that they added in to protect themselves from their own lovely practices. If they were using a type specifically for that request (or god forbid, an explicit primitive parameter for each value they might expect to receive) then they wouldn't have to worry about "over-posting". Or, if they explicitly pulled a record from the database and set the fields they wanted to change instead of just blindly setting the whole object as modified they could avoid this problem as well. Nevermind that they're accessing their database from their controller and using a private context available to the whole class rather than just scoped to the specific method. Nearly everything in these tutorials is a clusterfuck of bad practice.

This came off a bit more hostile than I was expecting - probably 'cause I've been spending more time than I should be trying to tell our new guy to unlearn nearly everything those tutorials have taught.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

RICHUNCLEPENNYBAGS posted:

I agree. But it suggests them for foreach loops too and honestly sometimes it gets a little heady for my tastes.

The things that ReSharper can generate from a foreach loop is absolutely mind-boggling. Why yes, of course I wanted this readable and understandable foreach block to be re-written with 3 SelectManys, 2 Aggregates, and a GroupJoin.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Munkeymon posted:

Look at Bognar's post about not passing models around.

Yeah, I was definitely just referring to data models there. If you have a parameter object that's specific to your function, then you don't run into the problems I was bitching about (e.g. modifying a data model can cause unexpected behavior in your methods that include it in its signature).

I'm not really a fan of parameter objects in general, though, mainly for the reason that if I change a method and add or remove a parameter then my code could still compile while being incorrect and defer the errors to runtime. If my method signature instead lists all of its requirements explicitly, I can't compile the code until I fix everything that the change broke. Obviously you should still have the runtime checks for invalid data being passed in, but I like to lean on the compiler wherever possible. This isn't exactly relevant in the situation of optional/named parameters, but I would still prefer those to parameter objects.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Sedro posted:

Really, all the language needs is some syntactic sugar for tuples, and that would be useful for more than just multiple return values. I shouldn't ever have to write Tuple.Create or tuple.Item1, tuple.Item2. They probably wanted to leverage the multiple return capabilities of the CLR.

We were talking about this at work today and my co-worker convinced me that being able to return anonymous types would be a better solution. It's a bit quirky, but it allows you to have named properties instead of just relying on the position in the tuple. It might look like:

C# code:
public var GetMostUsedCharacter(string input) {
	var mostUsed = input.GroupBy(c => c).OrderByDescending(g => g.Count()).First();
	return new { Letter = mostUsed.Key, Count = mostUsed.Count() };
}
It basically gives you everything that a tuple does, but adds named properties and employs a more commonly used language feature (I rarely see Tuple<>, but anonymous types are everywhere).

Sedro posted:

And the null coalesce syntax? Hooray, an untyped maybe monad that throws NREs.

I'm not sure I follow here. Isn't the point that it stops evaluating the expression once it encounters a null and thus doesn't throw NREs?

Bognar fucked around with this message at 03:29 on Jan 18, 2014

Adbot
ADBOT LOVES YOU

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

RICHUNCLEPENNYBAGS posted:

So return a dynamic then.

I mean I know people are afraid of them but they're useful for any number of things.

I honestly wish dynamics had never been added. I get that they're useful for making COM interop code not look terrible, but I feel like the solution is to build a sane wrapper API around common COM interaction rather than adding duck typing to a statically typed language. I don't have a problem with duck typing in and of itself, I just don't want it littered throughout my statically typed code. The compiler will check my errors in all my statically typed code, but the compiler only looks like it's checking my errors in dynamically typed code.

Also, just by virtue of having it as a language feature people will try to use it in places where it shouldn't be. This is one of those places.

Sedro posted:

They made some mention of structural types. In your example the return type would be something like { string Letter, int Count }.

I don't remember seeing this in the stuff I read, but I would be very pleased if that was added.

Sedro posted:

Well, in a language where any reference can be null, everything is a maybe, and you're not going to change every dereference into a maybe-dereference. So without the help of the compiler you have to read through API docs to see if things return null. And if you mess one up, NRE.

Obviously they can't fix null at this point, but advocating its use through language features seems like a bad idea.

I don't think that this new feature encourages people to use null any more than they already do. It's already everywhere and strictly unavoidable due to the language design, so this is just syntactic sugar to make working around it suck less.

Bognar fucked around with this message at 05:40 on Jan 18, 2014

  • Locked thread