How to reference parent variable with a different type without casting?
我有这种情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class Base { public Basedef def; } public class A : Base { } public class B : A { public int GetBar() { return def.bar; } } public class BaseDef { } public class ADef : BaseDef { public int foo; } public class BDef : ADef { public int bar; } |
如您所见,方法b:getbar()中有一个错误,因为def没有访问bar的权限,但是如果您使…
1 2 3 4 | public int GetBar() { return (def as BDef).bar; } |
应该可以,但我想避免强制转换,如何使用在基类中创建的引用从定义中获取属性而不使用强制转换?
为什么要避免演员阵容?,因为很容易出现运行时错误并且更容易引入错误,所以我需要类型安全的编码。
我想做的
1 2 3 4 5 6 7 8 9 10 11 12 13 |
我在找一个优雅的解决方案
再见!
为了有一个优雅的、无强制转换的解决方案,编译器需要知道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class Base<T> where T : BaseDef { public T def { get; set; } } public class A<T> : Base<T> where T : ADef { public int GetFoo() { return def.foo; // this works, too } } public class B : A<BDef> { public int GetBar() { return def.bar; } } |
(顺便说一下,你应该使用公共财产,而不是公共领域。老实说,公共变量和公共属性访问器有什么区别?出于某些原因。)
更新:您的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public static Base<T> Create<T>(T d) where T : BaseDef { if(typeof(T) == typeof(BDef)) return (Base<T>)(object)new B(); else return null; } public static T Create<T, U>(U d) where T : Base<U> where U : BaseDef { T result; if (typeof(T) == typeof(B)) result = (T)(object)new B(); else throw new NotImplementedException(); result.def = d; return result; } public static T CreateAlternate<T, U>(U d) where T : Base<U>, new() where U : BaseDef { return new T { def = d }; } |
用途:
1 2 3 4 5 6 |
我喜欢最后一个,因为没有强制转换,只要
Why avoid cast?, because is prone to runtime errors and is easier to introduce bugs, I want type-safe coding.
我不明白为什么Cast容易出错,如果你不知道
在我看来,你应该知道什么是它的运行时类型。
有解决办法
工作1:
1 2 3 4 5 6 7 |
工作2:介绍一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public enum DefType { BaseDef = 0, ADef =1, BDef =2 } public class BaseDef { public virtual DefType MyType { get{ return DefType.BaseDef; } } } public class ADef { public override DefType MyType { get{ return DefType.ADef; } } } |
然后像这样使用
1 2 3 4 5 6 7 8 | switch(def.MyType) { case DefType.ADef: { (ADef).foo;//you know who is this here right? } ... } |
用演员表做这件事是不安全的,因为你要做的基本上是不安全的。
您有一个类A和一个类B,它们是base的子类,base引用了basedef。basedef可以是adef或bdef,你不知道是哪一个,当然不是从任何告诉b的东西。
但是,如果使用泛型,可以向B提供需要知道其basedef引用实际上是bdef的信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class Base<T> where T : BaseDef { public T def; } public class A<T> : Base<T> where T : ADef { } public class B : A<BDef> { public int GetBar() { return def.bar; } } |
将basedef设置为abstact类并在其上禁止抽象属性是否有意义?