ReSharper红色强调VS 2010中的类型推断

时间:2011-06-04 23:23:25

标签: c# visual-studio-2010 resharper type-inference

我在VS 2010中遇到一个奇怪的错误。我有一个项目设置为使用.NET Framework 4.当我输入代码时:

var record = ...;

// returns IEnumerable<Staff>
var staff = new StaffRepository().GetAll(); 

// The method has two signatures:
// CreateSelectList(IEnumerable<object> enumerable, string value)
// CreateSelectList(IDictionary<object, object> enumerable, string value)
StaffList = SelectListHelper.CreateSelectList(staff, record.Staff);

CreateSelectList基本上采用可枚举的对象,使用ToString()将它们转换为字符串,然后自动选择传递的字符串。

问题是,此代码在VS 2010中出现红色下划线,并显示错误,表示无法解析该方法。

但是,如果我更改代码以明确说出类型:

IEnumerable<Staff> staff = new StaffRepository().GetAll();
StaffList = SelectListHelper.CreateSelectList(staff, record.Staff);

VS 2010不再给出错误。我对泛型的理解是这两个代码片段应该与编译器相同,那么为什么它给我一个错误下划线?

同时

这也将解决问题:

var staff = new StaffRepository().GetAll();
StaffList = SelectListHelper.CreateSelectList(from s in staff select s, record.Staff);

ReSharper的:

我尝试删除我的_ReSharper目录,但没有运气。我仍然得到下划线。但是,如果我暂停(即关闭)ReSharper,红色下划线就会消失,因此它肯定是由ReSharper引起的。

代码:

根据要求,这是代码。

这是StaffRepository:

namespace Foo.Client.Business.Repositories {
    public class StaffRepository : StaffRepositoryBase<Staff, StaffCriteria, Discriminator> {

        public StaffRepository(Discriminator discriminator) : base(discriminator) {
        }

        protected override Staff CreateStaff(MembershipUser user) {
            return new Staff(user);
        }

    } // end class
}

这是StaffRepositoryBase(定义了GetAll):

namespace Foo.Common.Business.Repositories {
    public abstract class StaffRepositoryBase<TStaff, TStaffCriteria, TDiscriminator> 
        : IStaffRepository<TStaff, TStaffCriteria, TDiscriminator>
        where TStaff : class, IStaff<TDiscriminator>
        where TStaffCriteria : class, IStaffCriteria {
        ...

        protected abstract TStaff CreateStaff(MembershipUser user);

        public virtual IEnumerable<TStaff> GetAll() {
            return from u in Membership.GetAllUsers().Cast<MembershipUser>()
                   let s = CreateStaff(u)
                   where s.Discriminator.Equals(Discriminator)
                   select s;
        }

        public virtual IEnumerable<TStaff> GetAll(LimitCriteria criteria) {
            var staffs = GetAll()
                .Skip(criteria.Skip.GetValueOrDefault())
                .Take(criteria.Take.GetValueOrDefault());

            return staffs;
        }

        public virtual IEnumerable<TStaff> GetAll() {
            return from u in Membership.GetAllUsers().Cast<MembershipUser>()
                   let s = CreateStaff(u)
                   where s.Discriminator.Equals(Discriminator)
                   select s;
        }

        ...
    }
}

5 个答案:

答案 0 :(得分:3)

我猜测返回类型是List而不是Ienumerable,而VS正在哭泣。我假设这两个代码都有效,但它喜欢明确的事情。

答案 1 :(得分:2)

您已在评论中说明该项目之前的目标是.NET3.5。

对于面向.NET 3.5的项目,Resharper将以您描述的方式强调下划线。鉴于您现在的目标是.NET4,Resharper仍然认为您出于某种原因使用.NET3.5。

你可以尝试

  1. 清除Resharper缓存(Resharper -> Options -> Environment/General -> Clear Caches
  2. 从头开始将项目(csproj)文件重新创建为.NET4项目
  3. 使用Resharper 6.0 Beta(刚出来),因为它似乎没有此问题

答案 2 :(得分:1)

当你输入时,VS会解释工作。当它无法确定变量的类型时,它会给出红色下划线错误。这可能是VS或其加载项的错误(例如Resharper,只是我猜)

编译时,C#编译器会完成所有的工作,查看所有引用并用适当的类型替换var,因此红色下划线错误消失了。

您可以尝试清理解决方案,关闭VS并重新启动它,这可能有所帮助,但值得一试

答案 3 :(得分:0)

问题是CreateSelectList需要IEnumerable<Object>,而不是IEnumerable<Staff>。即使Staff继承自Object,IEnumerable<Staff>也不会从IEnumerable<Object>继承。这是人们用泛型制作的一个常见错误。

我建议将CreateSelectList的签名更改为:

CreateSelectList<T>(IEnumerable<T> enumerable, string value)

答案 4 :(得分:0)

卸载和重装项目帮助我解决了这个问题。