是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()
?
如何在不更改返回myRepository
的情况下更改添加部分myEnum.Add(new Class1());
来执行myEnum.Add((new Class1() as TResult));
而不是IEnumerable<TResult>
?
答案 0 :(得分:2)
由于T(Baseclass或Baseclass的子级)之间没有隐式转换,因此检查ISpezial是否可分配(你做了哪些,并且它非常好)是不够的,你当将变量作为参数传递时,还需要显式强制转换变量,然后再将其强制转换。但是,它确实不是最好的班级设计。
entities = doSpecialStuff(entities.Cast<ISpezial>()).Cast<T>();
第二个问题:既然你明确地调用了Class2()和Class1()构造函数,那你就不是真的依赖于C#的多态/泛型类型,这就是new()约束存在的原因(如果你写的话)新的T(),例如)。因此,只要您保留代码,就可以删除约束。
第3名:您可以使用 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>();