1

在下面的代码中是一个在线问题,entities = doSpecialStuff(entities);因为我在我的doSpecialStuff()Methode部分“遗漏”了一些东西

Error
The type 'T' cannot be used as type parameter 'T' in the generic type or method
'myWorkClass<T>.doSpecialStuff<T>(IEnumerable<T> entities)'. There is no implicit reference conversion from 'T' to 'ISpezial'.)

代码

这是我的惯性结构

public class Baseclass { }

public interface ISpezial 
{ 
    int mySpecial{get;set;} 
}

public class Class1 : Baseclass { }

public class Class2 : Baseclass, ISpezial
{
    public int mySpecial{ get;set;}
}

这是我的数据提供者

public class myRepository
{
    public static IEnumerable<TResult> Load<TResult>() where TResult : Baseclass, new()
    {
        List<TResult> myEnum = new List<TResult>();

        if (typeof(ISpezial).IsAssignableFrom(typeof(TResult)))
        {
            myEnum.Add((new Class2() { mySpecial = 0 }) as TResult);
            myEnum.Add((new Class2() { mySpecial = 1 }) as TResult);
            myEnum.Add((new Class2() { mySpecial = 2 }) as TResult);
        }
        else
        {
            myEnum.Add((new Class1() as TResult));
            myEnum.Add((new Class1() as TResult));
            myEnum.Add((new Class1() as TResult));
        }

        return myEnum;
    }
}

那里的班级像老板一样做事并提供错误

public class myWorkClass<T> where T : Baseclass, new()
{
    public void doNormalStuff()
    {
        var entities = myRepository.Load<T>();
        if (typeof(ISpezial).IsAssignableFrom(typeof(T)))
        {
            entities = doSpecialStuff(entities);
        }
    }

    public IEnumerable<T> doSpecialStuff<T>(IEnumerable<T> entities) where T : ISpezial
    {
        var list = new List<T>();

        return list.Where(special => special.mySpecial==2);
    }
}

一些进一步的问题

我怎样才能避免new()在我的位置?

以及如何更改 Add 部分myRepositorymyEnum.Add(new Class1());不是myEnum.Add((new Class1() as TResult));更改 return IEnumerable<TResult>

4

1 回答 1

2

由于 T(Baseclass 或 Baseclass 的子级)之间没有隐式转换,因此仅检查 ISpezial 是否可分配(您这样做,而且非常好)是不够的,您还需要在将变量传递为时显式转换它一个参数,然后将其转换回去。不过,这真的不是最好的班级设计。

 entities = doSpecialStuff(entities.Cast<ISpezial>()).Cast<T>();

第二个问题:由于您显式调用 Class2() 和 Class1() 构造函数,因此您并没有真正依赖 C# 的多态性/泛型类型,这就是存在 new() 约束的原因(如果您编写了 new T(),例如)。因此,只要您保持这样的代码,就可以删除约束。

第三:您可以使用dynamics关键字,列出您的动态类型,并仅在最后一刻强制转换:

List<dynamic> myEnum = new List<dynamic>();
//your code
myEnum.Add((new Class2() { mySpecial = 0 })); //it's ok to write like you want it now
//your code
return myEnum.Cast<TResult>();
于 2013-05-03T08:25:38.547 回答