简体   繁体   English

无法将匿名类型#1 []隐式转换为匿名类型#2 []

[英]Cannot implicitly convert anonymous type #1[] to anonymous type #2[]

I have following scenario: 我有以下场景:

public JsonResult ChangeFilterList(int option)
{
    var data = new[] { new { Text = "Unknown option", Value = -1 } };
    switch (option)
    {
        case 2: data = _departmentnameRepository.All.Select(x => new { Text = x.DeptName, Value = x.Id }).ToArray();
            break;
        case 3: data = Session["projectid"] == null
                ? _assetSequenceRepository.All.Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray()
                : _assetSequenceRepository.FindBy(p => p.ProjectId == (int)Session["projectid"]).Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray();
            break;
        default: data = _userRepository.All.Select(x => new { Text = x.DisplayName, Value = x.UserID }).ToArray();
            break;
    }            

    return Json(data, JsonRequestBehavior.AllowGet);
}

case2 and default looks great but complains on case 3 (conditional) saying: Cannot implicitly convert type 'AnonymousType#1[]' to 'AnonymousType#2[]' . case2default看起来很棒,但在案例3(有条件的)上抱怨说: Cannot implicitly convert type 'AnonymousType#1[]' to 'AnonymousType#2[]' Shouldn't ?: be able to decide the type since i already have provided the blueprint for the anonymous as var data = new[] { new { Text = "Unknown option", Value = -1 } }; 不应该?:能够决定类型,因为我已经为匿名提供了蓝图,因为var data = new[] { new { Text = "Unknown option", Value = -1 } }; .

Solution: 解:

@Darin Dimitrov answer is great but i want to have some test with anonymous types (Simple cases always need it). @Darin Dimitrov答案很棒,但我希望对匿名类型进行一些测试(简单情况总是需要它)。 As @Douglas suspects : My assetSequenceRepository is supplying id as long and anonymous Value goes in favor of int not long . 正如@Douglas所怀疑的那样:我的assetSequenceRepository正在提供idlong而且匿名Value有利于intlong since C# compiler does not implicitly cast long to int , i got the error. 因为C#编译器没有隐式地将longint ,所以我得到了错误。 Compiling snippet is: 编译片段是:

public JsonResult ChangeFilterList(int option = 3)
        {
            var data = new[] { new { Text = "Unknown option", Value = long.MaxValue } };
            switch (option)
            {
                case 2: data = _departmentnameRepository.All.Select(x => new { Text = x.DeptName, Value = (long)x.Id }).ToArray();
                    break;
                case 3: data = Session["projectid"] == null
                        ? _assetSequenceRepository.All.Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray()
                        : _assetSequenceRepository.FindBy(p => p.ProjectId == (int)Session["projectid"]).Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray();
                    break;
                default: data = _userRepository.All.Select(x => new { Text = x.DisplayName, Value = (long)x.UserID }).ToArray();
                    break;
            }            

            return Json(data, JsonRequestBehavior.AllowGet);
        }

You are putting the compiler to a real test here. 您正在将编译器置于此处进行实际测试。 Just write a view model to end its suffering and make things more explicit: 只需编写一个视图模型来结束其痛苦并使事情更明确:

public class MyViewModel
{
    public int Value { get; set; }
    public string Text { get; set; }
}

and then project your LINQ queries to this view model to avoid any possible ambiguity that might arise from the use of the conditional operator and anonymous types: 然后将LINQ查询投影到此视图模型,以避免使用条件运算符和匿名类型可能产生的任何歧义:

public ActionResult ChangeFilterList(int option)
{
    var data = new[] 
    { 
        new MyViewModel { Text = "Unknown option", Value = -1 } 
    };

    switch (option)
    {
        case 2: data = _departmentnameRepository
            .All
            .Select(x => new MyViewModel { Text = x.DeptName, Value = x.Id })
            .ToArray();
            break;
        case 3: data = Session["projectid"] == null
                ? _assetSequenceRepository
                    .All
                    .Select(x => new MyViewModel { Text = x.AssetShotName, Value = x.Id })
                    .ToArray()
                : _assetSequenceRepository
                    .FindBy(p => p.ProjectId == (int)Session["projectid"])
                    .Select(x => new MyViewModel { Text = x.AssetShotName, Value = x.Id })
                    .ToArray();
            break;
        default: data = _userRepository
            .All
            .Select(x => new MyViewModel { Text = x.DisplayName, Value = x.UserID })
            .ToArray();
            break;
    }            

    return Json(data, JsonRequestBehavior.AllowGet);
}

My guess is that your FindBy method returns objects whose properties have different types from the ones you're expecting (eg int? instead of int ). 我的猜测是你的FindBy方法返回的属性与你期望的类型不同的对象(例如int?而不是int )。 Try specifying a type cast to ensure that your anonymous type has the correct definition: 尝试指定类型转换以确保您的匿名类型具有正确的定义:

case 3: data = Session["projectid"] == null
             ? _assetSequenceRepository.All.Select(x => new { Text = x.AssetShotName, Value = x.Id }).ToArray()
             : _assetSequenceRepository.FindBy(p => p.ProjectId == (int)Session["projectid"]).Select(x => new { Text = (string)x.AssetShotName, Value = (int)x.Id }).ToArray();
        break;

The key change is: 关键变化是:

new { Text = (string)x.AssetShotName, Value = (int)x.Id })
                  ↖    explicit type casts    ↗

Following test code compiles just fine: 以下测试代码编译得很好:

public void Test(int option, string parameter)
{
    var data = new[] { new { Text = "Unknown option", Value = -1 } };

    switch(option)
    {
        case 2:
            data = Enumerable.Range(1, 4)
                             .Select(x => new { Text = x.ToString(), Value = x })
                             .ToArray();
            break;
        case 3:
            data = (new Random()).Next(2) % 2 == 1
                ? Enumerable.Range(1, 6)
                            .Select(x => new { Text = x.ToString(), Value = x })
                            .ToArray()
                : Enumerable.Range(1, 2)
                            .Select(x => new { Text = x.ToString(), Value = x })
                            .ToArray();
            break;
        default:
            data = Enumerable.Range(1, 3)
                             .Select(x => new { Text = x.ToString(), Value = x })
                             .ToArray();
            break;
    }
}

I only changed your repository calls to Enumerable.Range() and Select lambda to get proper string / int properties values. 我只将您的存储库调用更改为Enumerable.Range()Select lambda以获取正确的string / int属性值。

I would guess, that you've shown use not exactly the code you're trying to compile. 我猜,你已经显示出使用的不完全是你想要编译的代码。 And in your real code you have one property with non-matching name (eg incorrect casing) or incorrect type. 在您的真实代码中,您有一个具有不匹配名称的属性(例如,不正确的大小写)或不正确的类型。

You can try to figure it out by hovering your mouse pointer over ToArray() call. 您可以通过将鼠标指针悬停在ToArray()调用ToArray()尝试找出它。 There will be a is new { string Text, int Value } printed on the tooltip. 将在工具提示上打印a is new { string Text, int Value }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法隐式转换类型<anonymous type></anonymous> - Cannot implicitly convert type <anonymous type> 无法将类型&#39;Anonymous Type#1 []&#39;隐式转换为&#39;int []&#39; - Cannot implicitly convert type 'Anonymous Type#1[]' to 'int[]' 不能隐式转换类型 List&lt;<anonymous type: ..> &gt; 到 IEnumerable<Product> - Cannot implicitly convert type List<<anonymous type: ..>> to IEnumerable<Product> 不能隐式转换类型 &#39;System.Collections.Generic.List&lt; - Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type C#无法隐式转换类型&#39;System.Linq.IQueryable &lt; - C# Cannot implicitly convert type 'System.Linq.IQueryable<<anonymous type: 无法将类型&#39;system.linq.iqueryable匿名类型#1&#39;隐式转换为byte [] - cannot implicitly convert type 'system.linq.iqueryable anonymous type#1' to byte[] Web API无法隐式转换类型&#39;System.Collections.Generic.List &lt; - Web API Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: 无法隐式转换类型 System.Collections.Generic.List&lt;<anonymous type:int,string,bool> &gt;</anonymous> - Cannot implicitly convert type System.Collections.Generic.List<<anonymous type:int,string,bool>> 隐式键入与匿名类型 - Implicitly Typed vs Anonymous Type 字典无法从 ' 转换<anonymous type> '</anonymous> - Dictionary cannot convert from '<anonymous type>'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM