使用var,访问范围外的内容,可能";以身作则&”;
本文关键字:可能 quot 以身作则 访问 var 范围 使用 | 更新日期: 2023-09-27 18:29:26
我在if语句中使用LinQ。也定义为var
,因为有几个不同类型的列。问题是,在if语句之后,我想执行foreach
,但由于var结果是在if语句内部定义的,因此无法在外部访问。
在研究了这个问题后,我在网上发现有人用"以身作则"来解决这个问题。但我似乎不明白它是如何工作的,也不明白如何根据我的实际例子进行调整。
以下是示例代码:
static IEnumerable<T> SequenceByExample<T>(T t) { return null; }
下面是我将在内部有不同LinQ查询的主要if语句:
if ((currentObject.CurrentAccount == "") && (currentObject.CurrentSector == "All"))
{
var result = from row in datatableMasterA.AsEnumerable()
group row by new
{
symbol = row.Field<string>("BloombergSymbol"),
desc = row.Field<string>("Description")
}
into grp
select new
{
symbol = (string)grp.Key.symbol,
desc = (string)grp.Key.desc,
delta = grp.Where(x => x.Field<string>("TD_Indicator") == "P").Select(r => r.Field<decimal>("Delta")).FirstOrDefault(),
prevQty = grp.Where(x => x.Field<string>("TD_Indicator") == "P").Sum(r => r.Field<Int64>("Qty_Net")),
prevPl = grp.Where(x => x.Field<string>("TD_Indicator") == "P").Sum(r => r.Field<double>("PL_USD")),
topQty = grp.Where(x => x.Field<string>("TD_Indicator") == "T").Sum(r => r.Field<Int64>("Qty_Net")),
topPl = grp.Where(x => x.Field<string>("TD_Indicator") == "T").Sum(r => r.Field<double>("PL_USD"))
};
CreateDatagridBreakdownPartB(result.ToArray());
}
//portfolio-single sector
else if ((currentObject.CurrentAccount == "") && (currentObject.CurrentSector != "All"))
{
}
//single account-all sectors
else if ((currentObject.CurrentAccount != "") && (currentObject.CurrentSector == "All"))
{
}
//single account-single sector
else if ((currentObject.CurrentAccount != "") && (currentObject.CurrentSector != "All"))
{
}
else
{
MessageBox.Show("Error in CreateDataGridBreakdown");
}
#endregion
//foreach (var x in result)
//{
//}
有人能在这个问题上帮我吗?非常感谢!
基本上,您应该遵循这个示例。
示例如下:
void YourMethod()
{
var arr = new int[5];
var anonim = arr.Select(x => new {value1 = "", value2 = "", value3 = "", value4 = 5});
var anonimAsTemplate = new {value1 = "", value2 = "", value3 = "", value4 = 5};
var anonimCasted = CastTo(anonim, anonimAsTemplate);
}
private static IEnumerable<T> CastTo<T>(Object value, T targetType)
{
// targetType above is just for compiler magic
// to infer the type to cast x to
return (IEnumerable<T>)value;
}
但这对于终身应用程序来说是一个非常非常糟糕的想法。除非,仅用于学习。相反,您应该使用真实的类来从LINQ语句返回。
假设您的匿名类型在所有if子句中都是相同的,并且您希望使用示例转换技巧,如这里所述,您需要:
创建这样的扩展方法:
public static T SequenceByExample<T>(this object o, T example)
{
return (IEnumerable<T>) o;
}
将代码更改为类似的内容:
Object result;
if ((currentObject.CurrentAccount == "")
&& (currentObject.CurrentSector == "All"))
{
result = from row in datatableMasterA.AsEnumerable()
group row by new
/* [...] */
然后foreach循环可以这样完成:
foreach (var item in result.SequenceByExample(new
{
symbol = "",
desc = "",
delta = 0M,
/*...*/
}))
话虽如此,认真考虑简单地创建您的实体类型:
class MyEntity
{
public String symbol { get; set; }
public String desc { get; set; }
public decimal delta { get; set; }
/* ... */
}
我建议您创建一个类来保存数据,比如:
public class MyClass{
public string Symbol { get; set; }
public string Description { get; set; }
}
然后在if
语句之前,定义结果列表:
List<MyClass> results;
然后在每个if
语句中,您可以像这样select
:
results = (from row in datatableMasterA.AsEnumerable()
group row by new
{
symbol = row.Field<string>("BloombergSymbol"),
desc = row.Field<string>("Description")
}
into grp
select new MyClass()
{
Symbol = (string)grp.Key.symbol,
Description = (string)grp.Key.desc,
//etc...
}).ToList();
你的foreach
应该没问题…
foreach (MyClass x in results)
{
string symbol = x.Symbol;
}