C# 使用var,访问范围外的内容,可能是“通过示例强制转换”

C# 使用var,访问范围外的内容,可能是“通过示例强制转换”,c#,linq,C#,Linq,我在if语句中使用LinQ。由于有几个不同类型的列,因此也定义为var。问题是,在if语句之后,我想执行foreach,但由于var结果是在if语句内部定义的,因此在外部无法访问 在研究了这个问题后,我在网上发现有人用cast by example来解决这个问题。但我似乎无法理解它是如何工作的,也无法根据我的实际例子调整它 下面是cast by示例代码: static IEnumerable<T> SequenceByExample<T>(T t) { return nu

我在if语句中使用LinQ。由于有几个不同类型的列,因此也定义为var。问题是,在if语句之后,我想执行foreach,但由于var结果是在if语句内部定义的,因此在外部无法访问

在研究了这个问题后,我在网上发现有人用cast by example来解决这个问题。但我似乎无法理解它是如何工作的,也无法根据我的实际例子调整它

下面是cast by示例代码:

static IEnumerable<T> SequenceByExample<T>(T t) { return null; }
下面是主if语句,我将在其中使用不同的LinQ查询:

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语句返回。

基本上,您应该遵循

示例如下:

    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语句返回。

我建议您创建一个类来保存数据,如下所示:

public class MyClass{
    public string Symbol { get; set; }
    public string Description { get; set; }
}
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 (var item in result.SequenceByExample(new
                                              {
                                                symbol = "",
                                                desc = "",
                                                delta = 0M,
                                                /*...*/
                                              }))
然后在if语句之前,定义结果列表:

List<MyClass> results;
你的车应该没问题

foreach (MyClass x in results)
{
    string symbol = x.Symbol;
}

我建议您创建一个类来保存数据,如下所示:

public class MyClass{
    public string Symbol { get; set; }
    public string Description { get; set; }
}
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 (var item in result.SequenceByExample(new
                                              {
                                                symbol = "",
                                                desc = "",
                                                delta = 0M,
                                                /*...*/
                                              }))
然后在if语句之前,定义结果列表:

List<MyClass> results;
你的车应该没问题

foreach (MyClass x in results)
{
    string symbol = x.Symbol;
}

假设您的匿名类型在所有if子句中都是相同的,并且您希望使用所述的cast by example技巧,您需要:

创建扩展方法,如下所示:

public static T SequenceByExample<T>(this object o, T example)
{
    return (IEnumerable<T>) o;
} 
然后foreach循环可以这样做:

public class MyClass{
    public string Symbol { get; set; }
    public string Description { get; set; }
}
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 (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; }
   /* ... */
}

假设您的匿名类型在所有if子句中都是相同的,并且您希望使用所述的cast by example技巧,您需要:

创建扩展方法,如下所示:

public static T SequenceByExample<T>(this object o, T example)
{
    return (IEnumerable<T>) o;
} 
然后foreach循环可以这样做:

public class MyClass{
    public string Symbol { get; set; }
    public string Description { get; set; }
}
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 (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; }
   /* ... */
}

首先,您的cast-by-example代码错误,您的代码什么也不做-每个if语句是否生成不同的select结构属性?是的,每个if选择不同的属性properties@solarissf:那么,您希望您的foreach在到达时如何知道对象结构?var不是魔术,它总是计算一个特定的类型,因此foreach只能期望1个类型,而不是4个不同的类型。如果你想坚持使用var,那么你需要有4个foreach循环,每个If语句中1个如果where子句不同,那么在If/else块之外定义你的基本查询,然后只需添加relevant where子句,例如result=result。where…首先,你把cast by-example代码搞错了,您的什么都不做-每个if语句是否产生不同的select结构属性?是的,每个if选择不同的属性properties@solarissf:那么,您希望您的foreach在到达时如何知道对象结构?var不是魔术,它总是计算一个特定的类型,因此foreach只能期望1个类型,而不是4个不同的类型。如果要坚持使用var,则需要有4个foreach循环,每个If语句中有1个。如果where子句不同,则在If/else块之外定义基本查询,然后再加上relevent where子句,例如result=result.where…感谢您的输入,并指出这不是获取输入的方式,并指出这不是获取输入的方式感谢您指出,我采用了创建新类的更好想法。总是喜欢找出最有效的方法!谢谢你指出这一点,我更倾向于创建一个新类。总是喜欢找出最有效的方法!我不知道反对票是为了什么,如果我的答案有问题,请告诉我,以便修改。这可能只是因为他们来自于前几天我对另一个问题感到恼火的几个人……不确定否决票是为了什么,如果我的答案有问题,请告诉我,以便修改。可能只是因为他们来自于前几天我在另一个问题上恼火的几个人。。。