2009-04-17 62 views
2

我一直在研究LINQ表达式的静态反射 - 非常酷!来自静态反射的动态字段?

我以为有一个想法 - 一个类是否有可能根据另一个类上的静态反射在一个类上“生成”字段?我特意想到了我在这里看到的Builder模式很多次。我想做一个流利的nhibernate风格的属性注册,在构建器上生成与我想构建的类相匹配的字段。 Soemthing像这样:像这样

public class Color 
{ 
    private Color() 
    { 
    } 
    public string Name { get; private set; } 

    public class Builder : BuilderBase<Color> 
    { 
     public Builder() 
     { 
      Property(x => x.Name); 
     } 
     public Build() 
     { 
      return built_up_color; 
     } 
    } 
} 

和支持的构造函数语法:

Color c = new Color.Builder() { Name = "Red" }.Build(); 

所有这一切的关键是减少我要重复定义颜色的性的判定的次数。我玩这个:

public class Color 
{ 
    private Color() 
    { 
    } 
    public string Name { get; private set; } 

    public class Builder 
    { 
     private Color _color = new Color(); 
     public string Name 
     { 
      get { return _color.Name; } 
      set { _color.Name = value; } 
     } 

     public Build() 
     { 
      return _color; 
     } 
    } 
} 

这当然可以工作,并列出属性相同的次数,但感觉更加灵活和不太灵活。似乎我应该可以在这里做一些匿名类型的东西?

回答

1

值得指出的是,有一个名为Color与Class.Drawing.Color相冲突的类可能是一个坏主意。

这是非常可能导致他人混乱(更糟糕的是System.Drawring.Color值语义的,而你的类有引用语义这可能会导致进一步的混乱)

我要指出的是什么你真的想要的是Named Optional Arguments。我建议现在加入繁琐的Builder类将会更加努力,并且一旦到达C#4.0就会更加痛苦。取而代之的是构造函数是必需的(或者如果需要避免类型签名冲突静态工厂方法)

0

我认为这是不可能的,你不能生成成员,除非明确声明它们。咬住项目符号并为Color声明构造函数。 PS:我认为静态反射是一个误称,唯一静态的是你想要引用的成员的查找 - 尽管它是一个好东西,但那不是很远。

+0

谢谢您的回答。我有一个颜色的构造函数,但它意味着再次参数化参数。您是否看到建造商“通过”颜色的问题? – n8wrl 2009-04-17 20:15:06

+0

我没有看到问题(除非迂腐模式:),但*我*没有看到建设者的观点。 – 2009-04-18 06:41:34

0

减少代码编写但使用反射来设置值。

诀窍是使用集合初始值设定项。它是类型安全的。

public class Color 
{ 
    private Color() 
    { 
    } 
    public string Name { get; private set; } 
    public int Prop2 { get; private set; } 

    public class Builder : Builder<Color> 
    { 
     public Builder() 
     { 
      // possible 
      _instance.Name = "SomeDefaultValue"; 
     } 
    } 
} 

class Builder<T> : IEnumerable<string> 
{ 
    protected T _instance = Activator.CreateInstance(typeof(T)); 

    public void Add<TProperty>(Expression<Func<T, TProperty>> prop, TProperty value) 
    { 
     StaticReflection.GetPropertyInfo(prop).SetValue(_instance, value, null); 
    } 

    public static implicit operator T(Builder<T> builder) 
    { 
     return builder.Build(); 
    } 

    public T Build() 
    { 
     return _instance; 
    } 

    IEnumerator<string> IEnumerable<string>.GetEnumerator() 
    { 
     // e.g. return iterator over the property names 
     throw new NotImplementedException(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return ((IEnumerable<string>)this).GetEnumerator(); 
    } 
} 

,并调用语法

var color = new Color.Builder 
{ 
    { x => x.Name, "foo" }, 
    { x => x.Prop2, 5 } 
}.Build(); 

// or 

var color = new Builder<Color> 
{ 
    { x => x.Name, "foo" }, 
    { x => x.Prop2, 5 } 
}.Build(); 

// or 

Color color = new Builder<Color> 
{ 
    { x => x.Name, "foo" }, 
    { x => x.Prop2, 5 } 
};