C# 可以在匿名类型的属性上实现setter

C# 可以在匿名类型的属性上实现setter,c#,generics,C#,Generics,考虑以下几点: var o = new { Foo = "foo", Bar = "bar" }; 此实例是只读的,因为匿名类型不像类那样实现setter: public class O { public String Foo { get; set; } public String Bar { get; set; } } 是否可以“打开”匿名实例并允许更改其属性?最好使用少于创建类所需的字符 我想也许这可以通过对象上的扩展方法来实现o.SetProperty(o.Foo,“F

考虑以下几点:

var o = new { Foo = "foo", Bar = "bar" };
此实例是只读的,因为匿名类型不像类那样实现setter:

public class O
{
    public String Foo { get; set; }
    public String Bar { get; set; }
}
是否可以“打开”匿名实例并允许更改其属性?最好使用少于创建类所需的字符


我想也许这可以通过对象上的扩展方法来实现<代码>o.SetProperty(o.Foo,“Foo!”),如果您不能在对象构造时在线实现setter。

否,因为C#中的匿名类型是设计不变的

不,因为C#中的匿名类型是设计不变的

匿名类型在设计上是不可变的,因此您无法更改它们的状态。您可以使用反射(正如MarkGravell正确指出的那样),但无论从设计角度还是从性能角度来看,这都不是理想的性能

您有多种选择来解决此问题:

  • 使用元组而不是注释性类型。请注意,它们也是不可变的,但您可以更轻松地使用它们来创建方法,如
    tupleA.WithItem2(newValueForItem2)
    。类似于
    字符串
  • 使用自动属性编写自己的“命名”类型,通常很简单
  • 使用像CodeRush这样的重构工具,它可以根据您的使用情况生成“命名”类型

匿名类型在设计上是不可变的,因此您无法更改它们的状态。您可以使用反射(正如MarkGravell正确指出的那样),但无论从设计角度还是从性能角度来看,这都不是理想的性能

您有多种选择来解决此问题:

  • 使用元组而不是注释性类型。请注意,它们也是不可变的,但您可以更轻松地使用它们来创建方法,如
    tupleA.WithItem2(newValueForItem2)
    。类似于
    字符串
  • 使用自动属性编写自己的“命名”类型,通常很简单
  • 使用像CodeRush这样的重构工具,它可以根据您的使用情况生成“命名”类型

好吧,匿名类型是(事实上,问题被标记为C)。我只是强调这是特定编译器的一项功能,而不是“匿名类型”本身。@Marc:这一点很好,我想让匿名类型不可变的原因首先与它们在LINQ中的典型使用方式有关。+1谢谢。我接受了约翰尼斯更详细的回答。它涉及到几个备选方案。好吧,匿名类型是(事实上,问题被标记为C)。我只是强调这是特定编译器的一项功能,而不是“匿名类型”本身。@Marc:这一点很好,我想让匿名类型不可变的原因首先与它们在LINQ中的典型使用方式有关。+1谢谢。我接受了约翰尼斯更详细的回答。它涉及到一些替代方案,关于反射的说法是无效的:下面的方法很好:`var obj=new{id=1,name=“abc”};obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Single(f=>f.FieldType==typeof(int)).SetValue(obj,456);控制台写入线(对象id)`关于反射的声明是无效的:以下操作很好:`var obj=new{id=1,name=“abc”};obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Single(f=>f.FieldType==typeof(int)).SetValue(obj,456);控制台写入线(对象id)`