Search code examples
c#keywordmethod-declaration

Can I use the keyword "in" to separate parameters in a method declaration somehow?


I would like to create a method that uses the keyword in instead of a comma to separate parameters in a method declaration; something similar to the foreach(a in b) method.

Example

Class Structure

public class Length
{
    public double Inches;
    public double Feet;
    public double Yards;

    public enum Unit { Inch, Foot, Yard }

    Dictionary<Unit, double> inchFactor = new Dictionary<Unit, double>()
    {
        { Unit.Inch, 1 },
        { Unit.Foot, 12 },
        { Unit.Yard, 36 }
    };

    public Length(double value, Unit unit)
    {
        this.Inches = value * inchFactor[unit];
        this.Feet = this.Inches / inchFactor[Unit.Foot];
        this.Yards = this.Inches / inchFactor[Unit.Yard];
    }
}

Method Definition in Class

// I'd like to know how to use "in" like this  ↓
public List<Length> MultiplesOf(Length divisor in Length dividend)
{
    double inchEnumeration = divisor.Inches;
    List<Length> multiples = new List<Length>();

    while (inchEnumeration <= dividend.Inches)
    {
        multiples.Add(new Length(inchEnumeration, Length.Unit.Inch));
        inchEnumeration += divisor.Inches;
    }

    return multiples;
}

Ideal Implementation

private void DrawRuler()
{
    Length eighthInch = new Length(0.125, Length.Unit.Inch);
    Length oneFoot = new Length(1, Length.Unit.Foot);

    // Awesome.
    List<Length> tickGroup = Length.MultiplesOf(eighthInch in oneFoot);

    double inchPixels = 10;
    foreach (Length tick in tickGroup)
    {
        // Draw ruler.
    }
}

I've looked into creating new keywords, but it looks like C# does not support defining keywords.


Solution

  • While you can't redefine an existing keyword, there is other way to accomplish what you in a slightly different way using Fluent Interface :

    public class Length
    {
        // ...
    
        public static IFluentSyntaxProvider MultiplesOf(Length divisor)
        {
            return new FluentSyntaxProvider(divisor);
        }
    
        public interface IFluentSyntaxProvider
        {
            List<Length> In(Length dividend);
        }
        private class FluentSyntaxProvider : IFluentSyntaxProvider
        {
            private Length divisor;
    
            public FluentSyntaxProvider(Length divisor)
            {
                this.divisor = divisor;
            }
    
            public List<Length> In(Length dividend)
            {
                double inchEnumeration = divisor.Inches;
                List<Length> multiples = new List<Length>();
    
                while (inchEnumeration <= dividend.Inches)
                {
                    multiples.Add(new Length(inchEnumeration, Length.Unit.Inch));
                    inchEnumeration += divisor.Inches;
                }
    
                return multiples;
            }
        }
    }
    

    Example of usage :

    // Awesome.
    List<Length> tickGroup = Length.MultiplesOf(eighthInch).In(oneFoot);