gpt4 book ai didi

c# - 匿名类、临时数据和匿名类的集合

转载 作者:行者123 更新时间:2023-11-30 14:42:03 25 4
gpt4 key购买 nike

我是匿名类的新手,今天我想我遇到了第一个我觉得我真的可以使用它们的案例。我正在编写一个方法,该方法将受益于在类内部存储临时数据,并且由于该类在该方法之外没有任何意义,因此使用匿名类对我来说确实有意义(至少在当时是这样) ).

开始编码后,我似乎不得不做出一些让步。我喜欢将计算之类的东西分配给临时变量,这样在调试期间我可以一次验证逻辑 block 中的一些计算。然后我想为最终值分配一些更简单的东西。该值将在匿名类中。

问题是为了简洁地用匿名类实现我的代码,我想使用 LINQ。这里的问题是我不认为你可以在声明中进行这样的临时计算。 或者你可以吗?

这是我想做的一个人为的例子:

namespace AnonymousClassTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
ObservableCollection<RectanglePoints> Points { get; set; }

public class RectanglePoints
{
public Point UL { get; set; }
public Point UR { get; set; }
public Point LL { get; set; }
public Point LR { get; set; }
}

public class DontWantThis
{
public double Width { get; set; }
public double Height { get; set; }
}

private Dictionary<string,string> properties = new Dictionary<string,string>();
private Dictionary<string,double> scaling_factors = new Dictionary<string,double>();

private void Sample()
{
// not possible to do temp variables, so need to have
// longer, more unreadable assignments
var widths_and_heights = from rp in Points
select new
{
Width = (rp.UR.X - rp.UL.X) * scaling_factors[properties["dummy"]],
Height = (rp.LL.Y - rp.UL.Y) * scaling_factors[properties["yummy"]]
};

// or do it in a for loop -- but then you have to use a concrete
// class to deal with the Width and Height storage
List<DontWantThis> other_widths_and_heights = new List<DontWantThis>();
foreach( RectanglePoints rp in Points) {
double base_width = rp.UR.X - rp.UL.X;
double width_scaling_factor = scaling_factors[properties["dummy"]];
double base_height = rp.LL.Y - rp.UL.Y;
double height_scaling_factor = scaling_factors[properties["yummy"]];

other_widths_and_heights.Add( new DontWantThis
{
Width=base_width * width_scaling_factor,
Height=base_height * height_scaling_factor
});
}

// now we want to use the anonymous class, or concrete class, in the same function
foreach( var wah in widths_and_heights)
Console.WriteLine( String.Format( "{0} {1}", wah.Width, wah.Height));
foreach( DontWantThis dwt in other_widths_and_heights)
Console.WriteLine( String.Format( "{0} {1}", dwt.Width, dwt.Height));
}

public Window1()
{
InitializeComponent();
Points = new ObservableCollection<RectanglePoints>();
Random rand = new Random();
for( int i=0; i<10; i++) {
Points.Add( new RectanglePoints { UL=new Point { X=rand.Next(), Y=rand.Next() },
UR=new Point { X=rand.Next(), Y=rand.Next() },
LL=new Point { X=rand.Next(), Y=rand.Next() },
LR=new Point { X=rand.Next(), Y=rand.Next() }
} );
}

Sample();
}
}
}

注意:除非您实际将键添加到字典中,否则不要尝试运行它 :)

在 LINQ 中创建匿名类很棒,但迫使我在一行中进行计算。想象一下,计算器比我展示的要长得多。但它的相似之处在于我会进行一些字典查找以获取特定值。调试可能很痛苦。

具体类的使用解决了使用临时变量的问题,但我不能简洁地完成所有事情。是的,我意识到我在寻求简洁的同时要求能够在我的 LINQ 语句中保存临时变量有点矛盾。

我开始尝试在遍历 Points 时创建一个匿名类,但很快意识到我无法存储它!您不能使用 List,因为那样只会失去类的整个匿名性。

任何人都可以建议一种方法来实现我正在寻找的东西吗?或者一些中间立场?我在 StackOverflow 上阅读了其他一些问题,但没有一个与我的完全相同。

最佳答案

假设我理解正确,问题是您必须在单个表达式中设置所有属性。匿名类型绝对是这种情况。

但是,您不必在该表达式中全部内联。我建议,如果您的属性基于复杂的表达式,则将这些表达式分解为辅助方法:

var complex = new {
First = ComputeFirstValue(x, y),
Second = ComputeSecondValue(a, b)
...
};

如果您是白盒测试的粉丝(我是),这还有一个额外的潜在好处,即您可以单独对每个辅助方法进行单元测试。

这不会避免在一个大的匿名类型初始化表达式中出现,但这意味着工作将被分解。

关于c# - 匿名类、临时数据和匿名类的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3451228/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com