2017-10-12 131 views
0

我希望能够创建一个对任何成员变量执行通用操作的函数。C#模板访问对象成员

class line 
{ 
    double angle; 
    double length; 
    public void add(reference member, double scalar) 
    { 
     this.member *= scalar; 
    } 
} 

这是可能在C#中。如果我有很多成员变量,我不想创建一个巨大的开关盒。我也不想为每个成员变量创建一个lambda函数,因为操作会相同。

回答

0

大厦关闭@ askpark的回答,我拿出一些简单的

class line 
{ 
    double angle; 
    double length; 

    public void delegate adder(line l, double d); 
    static adder angleAdder = (l,d) => {l.angle += d}; 
    static adder lengthAdder = (l,d) => {l.length += d}; 

    public void add(adder addFunc, double scalar) 
    { 
     addFunc(this, scalar); 
    } 
} 
+1

您可以使用动作<线,双>而不是创建一个新的代表 – aspark

0

不需要仿制药。不过,您必须为不同的标量类型重载。没有办法在C#中使用泛型标量进行算术运算。为此,你需要一个类型约束where T : scalar,不幸的是,它不存在(也可能不存在)。

class line 
{ 
    double angle; 
    double length; 

    public void add(ref double member, double scalar) 
    { 
     member *= scalar; 
    } 

    public void test() 
    { 
     add(ref angle, 12); 
    } 

} 

你也可以将此定义为扩展方法的任何类:

public static class Extensions 
{ 
    public static double add(this object o, ref double d1, double d2) 
     => d1 *= d2; 
} 

但你必须明确地与this.前缀是:如下

private double _x = 1.0; 
public void Test() 
{ 
    // "The name 'add' does not exist in the current context" 
    add(ref _x, 1.2); 

    // This compiles 
    this.add(ref _x, 1.2); 
} 
0

使用反射,现在可以这样操作:line.Add(l => l.Length, 10)line.Add("Length", 10)line.Add(nameof(line.Length), 10)(env> .net 4.5)

你也可以重复这样的特殊成员:(new List<string> { "Length", "Height" }).ForEach(p => line.Add(p, 10))

class Line 
{ 
    public int Length { get; set; } 

    public double Height { get; set; } 

    public void Add<O>(Expression<Func<Line, O>> accessor, dynamic scale) where O : struct 
    { 
     Add((accessor.Body as MemberExpression).Member.Name, scale);//simply get name from expression 
    } 

    public void Add(string name, dynamic scale) 
    { 
     var prop = typeof(Line).GetProperty(name);//can also get all members 
     dynamic a = prop.GetValue(this); 
     prop.SetValue(this, a * scale); 
    } 
}