public abstract class Animal{} public class Dog:Animal{ public int Legs{ get; set;} } public class An<T>where T:Animal{ public List<T> l = new List<T>();//给v中保存Dog类型数据 public void Print(){ foreach (var v in l) Console.WriteLine(l.Legs);//怎么访问v中的Legs? } }
你的是T是Animal,animal没有Leg,Leg是Dog的;因此需要判断 v is Dog 然后 (v as Dog).Leg;
除非你t直接是Dog你上面就可以直接通过了。
可以可以了,第一次发现还有 v as Dog 这个属性,完美的解决了这段时间一直以来的困惑!!O(∩_∩)O谢谢
public void Print(){ foreach (var v in l) if (v is Dog) { (v as Dog).Legs = 6; Console.WriteLine ((v as Dog).Legs); } }
感谢感谢!!我去好好看看这个语法,嘿嘿嘿
给它转型试试? 转型后 看能不能得到legs这个属性
转型不行,父类对象是强转不了子类对象的,2楼方法完美解决,哈哈哈。谢谢解答~~
@风人: 是的 忘记判断了
不太好办,你T类型限制在animal上了,变通点的做法是把dog.legs通过委托带进去(带狗腿!?)
void Print(Func<T,object> printQuery)
{
...
Console.WriteLine(printQuery(v));
}
这样就是感觉挺麻烦的,如果要用到的数据更多的话就感觉好糟糕--
2楼方法觉得很好,,嘿嘿嘿,谢谢解答~~
@风人: 这个。。。。你泛型这样用的姿势不太对。
@Daniel Cai: 是挺别扭--刚学,不太会用。。
@风人: 泛型限制的有点好处就是编译安全性,如果一强转那么就失去了这个保证,而且同时增加了对实现的耦合度。
这里正确姿势是提个接口,接口方法的用途就是返回狗腿鸡毛啥的玩意(看你需求),Print方法继续加泛型限制Print<V>() where V:T,ICountable (ICountable返回狗腿数量)
这样就能在保证安全性的同时保证灵活性。
@Daniel Cai: 感谢指导~~
public class Animal{} public interface GetDogColumn{ int Legs{ get; set;} } public class Dog:Animal,GetDogColumn{ public int Legs{ get; set;} } public class An<T>where T:Animal{ public List<T> l = new List<T>();//给v中保存Dog类型数据 public void Print(){ foreach (var v in l) { Dog _dog = v as Dog; if (_dog != null) { _dog.Legs = 6; Console.WriteLine (_dog.Legs); } } } public void Print<V>()where V:T,GetDogColumn{//Print方法继续加泛型限制 foreach (V v in l) { v.Legs = 4; Console.WriteLine (v.Legs); } } }
是这样写吗?我试了下,可以实现想要的功能--
那就是用这个方法就是比用 as 强转更好吗?
@风人: 恩
ps
1..net中约定俗成接口以大写I卡头,一般接口命名能表达的意思为可以干什么(Ixxxable),仅做标识的接口可以不这样干,比如IRequireSessionState等。
2.单纯针对你现在的需求当然这样写属于过度设计,但当功能复杂,对象关系较多后这样写的好处就会体现出来了。
@Daniel Cai: 嗯嗯嗯,刚才又试了试访问Animal两个子类的特有的属性,更加理解了~~
非常感谢你的指导!O(∩_∩)O谢谢
2l的方法是好.但是你的问题就是错的.
既然泛型了.就不可能还限定子类.限定子类了.还泛型干嘛.
这个确实是,就是现在学到这,觉得这样定义一个容器类挺好的:
用一个泛型数组来保存Animal类各种子类的数据,就是可以定义一个An<Dog>对象来保存n个Dog类对象,也可以定义一个An<Pig>来保存n个Pig对象(Pig也是Animal的子类),因为Dog和Pig都是Animal子类,所以用泛型约束成Animal基类约束。并且在这个泛型容器类里对这个数组进行操作。