Joe Amenta

My feedback

  1. 186 votes
    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)

      We’ll send you updates on this idea

      For the Find by Status feature, we’re working on an extension to add this capability back to VS. We don’t yet have an ETA for the availability, but I’ll update here when it’s ready.

      For tfpt online, scorch, and treeclean, the functionality has been replaced by tf reconcile. If you use tfpt {command} /help, you’ll see a message about the specific options to use to get equivalent functionality with tf reconcile.

      Tfpt uu doesn’t have a replacement in tf.exe. The old tfpt commands should continue to work against newer versions of TFS and VSTS.

      Thanks,
      Matt Mitrik
      Program Manager | VSTS

      Joe Amenta commented  · 

      "The old tfpt commands should continue to work against newer versions of TFS and VSTS." -- this is mostly working for me fine, but apparently in some cases, "tfpt unshelve /migrate ..." is giving me "Unable to determine the workspace." even though "tf workfold" finds it just fine.

      Joe Amenta supported this idea  · 
    • 362 votes
      Vote
      Sign in
      Check!
      (thinking…)
      Reset
      or sign in with
      • facebook
      • google
        Password icon
        I agree to the terms of service
        Signed in as (Sign out)
        You have left! (?) (thinking…)
        6 comments  ·  Visual Studio IDE » Languages - C#  ·  Flag idea as inappropriate…  ·  Admin →
        Joe Amenta commented  · 

        There's System.Runtime.CompilerServices.Unsafe and ref locals / ref returns in C# 7.0 now (the former requires the latter to work properly), which together enable basically the same stuff (just not anywhere nearly as safely as a language feature would be)... the equivalents to what's in the original suggestion would look approximately like:

        unsafe void DoSomeStuff<T>() where T : struct
        {
        T t = default(T);
        ref T tPointer = ref t;

        // omitted aBunchOfT because it'd just look the same as...

        var tSize = Unsafe.SizeOf<T>();
        byte* aBunchOfBytes = stackalloc byte[tSize * 100];
        ref T aBunchOfCastedT = ref Unsafe.AsRef<T>(aBunchOfBytes);
        }

        System.Runtime.CompilerServices.Unsafe then adds a bunch of helper methods that let you do basically all the same stuff with "aBunchOfCastedT" that you can do with a pointer. You can also get a void* from the managed pointer with Unsafe.AsPointer<T>(ref T value), just make sure that you can prove to yourself that your managed pointer isn't an interior pointer to something that the GC could relocate if it wanted to, since it obviously won't know to fix up the returned unmanaged pointer at the same time like it would with the managed interior pointer.

        It's definitely clunky since it's implemented in a library API instead of directly in the language, and it would still be nice to have an "unmanaged" type constraint so we could use this more safely if the generic type parameter could come in from shady folks, but it at least gives insane people like me the tools needed to implement the internals of certain things in a way that makes the (probably more sane) users happier about how much faster it is, all the same.

        Joe Amenta supported this idea  · 
      • 129 votes
        Vote
        Sign in
        Check!
        (thinking…)
        Reset
        or sign in with
        • facebook
        • google
          Password icon
          I agree to the terms of service
          Signed in as (Sign out)
          You have left! (?) (thinking…)
          8 comments  ·  Visual Studio IDE » .NET  ·  Flag idea as inappropriate…  ·  Admin →
          Joe Amenta commented  · 

          As others have pointed out, this really is a breaking change. There's basically zero chance of it being done in the full framework. "Basically zero" means it's hypothetically possible, but the options for how to do it feel pretty insane (to me) for the very small set of minor use cases where this would be desirable.

          For a bit more details, the main breaking case I can think of is that if you have a class that implements IList<T> explicitly (i.e., "int IList<T>.Count { get { return 4; } }"), then this change as desired breaks your class because Count is on IReadOnlyList<T>.

          The workaround that works in probably 90% of cases: just have your collection class implement both interfaces (where the implementation of IList<T> methods that modify the collection are all implemented explicitly to throw NotSupportedException). e.g., https://goo.gl/jejFTH. As far as I've seen, the BCL team did a really good job at this for the BCL collections where it made sense (the IReadOnlyFoo<T> interfaces are really easy to implement, especially if you're already implementing IFoo<T>).

          I guess you could also make a sub-interface that implements or composes both IList<T> and IReadOnlyList<T> and pass that around in your app.

          If you have no choice but to call a method with IReadOnlyList<T> in its signature given absolutely nothing but an IList<T> instance, you can always just allocate a ReadOnlyCollection<T> instance at the method call boundary to wrap the IList<T> you were given. Allocations are not free, but they're probably cheap enough for most use cases. You can even just try-cast as a last-ditch effort to avoid the allocation cost in many situations if performance is important to you (if the performance of the try-cast is unacceptable, then you should probably consider your use of interfaces in the first place, I'm guessing).

          There are just so many workarounds for such a small wart, where the alternative is such an annoying thing, that it really feels like a no-brainer (especially at this point) not to pursue this one further.

          Though to echo what others have said, this would in fact be a desirable and consistent thing to have if the framework were written from the ground up. "Read only" = "I will ONLY need to READ from this list", as opposed to "this instance ONLY supports procedures that READ the data", which is in the realm of System.Collections.Immutable.

        • 189 votes
          Vote
          Sign in
          Check!
          (thinking…)
          Reset
          or sign in with
          • facebook
          • google
            Password icon
            I agree to the terms of service
            Signed in as (Sign out)
            You have left! (?) (thinking…)
            19 comments  ·  Visual Studio IDE » Languages - C#  ·  Flag idea as inappropriate…  ·  Admin →
            Joe Amenta supported this idea  · 
            Joe Amenta commented  · 

            I approve of params IEnumerable<T> as a counterpart to params T[], and I approve of having this be the only new "params type". While "params IReadOnlyCollection<T>" / "params IReadOnlyList<T>" would be marginally useful in narrow circumstances where we'd like to know the number of elements or access them by index, a "try-cast" approach could be done with a "params IEnumerable<T>" solution to get this behavior where available without terrible grief.

            "params IEnumerable<T>" solves a significant wart with the current "params T[]" approach. If I want to have a method with "params" goodness but also loop over the input lazily, I need to have one overload that takes "IEnumerable<T>" (no "params") and an overload that takes "params T[]", where the latter probably just calls the former. This is ugly. With "params IEnumerable<T>", I would write just one method that does everything I want.

          • 315 votes
            Vote
            Sign in
            Check!
            (thinking…)
            Reset
            or sign in with
            • facebook
            • google
              Password icon
              I agree to the terms of service
              Signed in as (Sign out)
              You have left! (?) (thinking…)
              1 comment  ·  Visual Studio IDE » Languages - C#  ·  Flag idea as inappropriate…  ·  Admin →
              Joe Amenta supported this idea  · 
            • 2,068 votes
              Vote
              Sign in
              Check!
              (thinking…)
              Reset
              or sign in with
              • facebook
              • google
                Password icon
                I agree to the terms of service
                Signed in as (Sign out)
                You have left! (?) (thinking…)
                19 comments  ·  Visual Studio IDE » Languages - C#  ·  Flag idea as inappropriate…  ·  Admin →
                Joe Amenta supported this idea  · 

              Feedback and Knowledge Base