【问题标题】:Can I use the keyword "in" to separate parameters in a method declaration somehow?我可以使用关键字“in”以某种方式分隔方法声明中的参数吗?
【发布时间】:2016-01-15 22:23:52
【问题描述】:

我想创建一个使用关键字in 而不是逗号来分隔方法声明中的参数的方法;类似于foreach(a in b) 方法。

示例

类结构

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];
    }
}

类中的方法定义

// 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;
}

理想的实现

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.
    }
}

我研究过创建新关键字,但 C# 似乎不支持定义关键字。

【问题讨论】:

  • 你不能。该语法采用无效的 C# 语法。 foreach(a in b) 是该关键字的有效语法,不能被其他方法使用。
  • "C# 好像不支持定义关键字" 正确。
  • @DStanley :当我查看 foreach 循环的源代码文件时,我认为这可能是可能的。它看起来像普通的 C#。我们是否无法访问与 System 和其他命名空间对其方法声明所做的相同资源?
  • @Micky:我做到了。它甚至不会编译。 ) expected
  • @TylerPantuso:您熟悉哪种语言支持定义关键字?任何 C 派生语言 AFAIK 都不支持自定义关键字。

标签: c# keyword method-declaration


【解决方案1】:

正如 cmets 中提到的,您不能在 C# 中定义自定义关键字(除非您扩展编译器,这是一项高级任务)。但是,如果您的目标是澄清这两个参数的含义,那么我建议您改用named arguments

// Define the method as usual:
public List<Length> MultiplesOf(Length divisor, Length dividend)
{
    // ...
}

// Then call it like so, explicitly showing what is the divisor and the dividend:  
List<Length> tickGroup = Length.MultiplesOf(divisor: eighthInch, dividend: oneFoot);

【讨论】:

    【解决方案2】:

    虽然您无法重新定义现有关键字,但还有其他方法可以使用 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;
            }
        }
    }
    

    使用示例:

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

    【讨论】:

    • 这很好用。我一直想知道如何做这样的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2014-03-04
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 2021-07-30
    相关资源
    最近更新 更多