Coffeehouse Thread

5 posts

Unconventional use of indexers

Back to Forum: Coffeehouse
  • User profile image
    dcuccia

    I'm playing around with trying to make array math in C# as easy and concise as in Matlab, and (besides array operators) the biggest language "mismatch" is in indexers, ranges, etc. In Matlab, I can easily get a subarray of A, such as A[0:5:255]

    As a user of a fluent interface DSL in C#, would you ever put up with unconventional use of indexers? Like:

    A[Get.Range[0,5,255]]


    ...where Range is actually a static readonly field holding an instance of class Range

        public class Get
        {
            public static readonly Range Range = new Range();
            public static readonly Size Size = new Size();
        }
    
        public class Range
        {
            public Range this[int from, int to] { get { return new Range(from, 1, to); } }
            public Range this[int from, int every, int to] { get { return new Range(from, every, to); } }
    
            private Range(int start, int every, int stop) { Start = start; Every = every;  Stop = stop; }
            private Range(int start, int stop) : this(start, 1, stop) { }
            internal Range() { } // for indexer use
    
            public int Start { get; private set; }
            public int Stop { get; private set; }
            public int Every { get; private set; }
            public int Count() { return (Stop - Start) / Every + 1; }
        }
    
        public class Size
        {
            public Size this[int d0] { get { return new Size(new int[] { d0 }); } }
            public Size this[int d0, int d1] { get { return new Size(new int[] { d0, d1 }); } }
            public Size this[int d0, int d1, int d2] { get { return new Size(new int[] { d0, d1, d2 }); } }
            public Size this[int d0, int d1, int d2, int d3] { get { return new Size(new int[] { d0, d1, d2, d3 }); } }
    
            private Size(int[] dimensions) { Dimensions = dimensions.ToArray(); }
            internal Size() { } // for indexer use
    
            public int[] Dimensions { get; private set; }
        }
    


    Obviously the following would be more C-sharpy:

    A[new Range(0,5,255)]


    But, isn't it OK to stray a bit as long as there's a consistent convention in the DSL?

  • User profile image
    Ion Todirel

    you may also want to make  the constructor of the Range class internal, to force the user to use it via Get class (if you use first approach), I would suggest to use the second one, but the first one looks cooler...

  • User profile image
    stevo_

    Ion Todirel said:
    you may also want to make  the constructor of the Range class internal, to force the user to use it via Get class (if you use first approach), I would suggest to use the second one, but the first one looks cooler...
    I'd be honest and say I don't think it adds anything or makes it really different, to me it just serves as a barrier for people to realize whats actually going on here..

  • User profile image
    dcuccia

    stevo_ said:
    Ion Todirel said:
    *snip*
    I'd be honest and say I don't think it adds anything or makes it really different, to me it just serves as a barrier for people to realize whats actually going on here..
    Thanks for the thoughts Ion and stevo_.

    Is the "Get" class a barrier too? If you had factory methods, which would you prefer (assuming "Get" is used for many purposes in the DSL)?

    A[Get.Range(0,5,255)]


    or a classic

     A[Range.GetRange(0,5,255)]

  • User profile image
    JChung2006

    I would prefer A.Range(from, to) and A.Range(from, to, every) rather than the indexer, but that's just my opinion.

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.