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
| public class Factory
{
public static Base<BaseDef > Create (BaseDef d )
{
if(d is BDef )
return new B (); //Error, can not convert B to Base<BaseDef>
}
}
public class Program
{
B instance = Factory .Create(new BDef ()); //Error, can not convert to Base<BaseDef> to B
} |
我在找一个优雅的解决方案
再见!
- 我想你希望ADEF从basedef继承,但是你没有写它,所以将basedef强制转换成bdef是没有意义的…
- 你为什么要避免演员阵容?没有虚拟方法或属性/反射,您试图实现的目标是不可能实现的。
- 我已经编辑了你的问题,假设你是指这个ADef : BaseDef。如果不编辑你的问题
- 斯里拉姆,是的,我是说,谢谢你指出
- sriram,更新了问题,补充了为什么我要避免铸造
为了有一个优雅的、无强制转换的解决方案,编译器需要知道def是GetBar()中的BDef。这是一种方法,我认为这对您的情况很有效:
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;
}
} |
(顺便说一下,你应该使用公共财产,而不是公共领域。老实说,公共变量和公共属性访问器有什么区别?出于某些原因。)
更新:您的Factory方法可能如下所示:
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
| void Main ()
{
Factory .Create(new BDef ());
Factory .Create<B, BDef >(new BDef ());
Factory .CreateAlternate<B, BDef >(new BDef ());
} |
我喜欢最后一个,因为没有强制转换,只要new()约束不是问题,或者第一个(如果简洁的调用代码是非常有价值的)约束(因为可以推断出泛型类型)。
- 我考虑过这个问题,a可以使用其def引用获取foo值吗?
- @JoeCabezas是的,我的解决方案支持这一点,因为编译器知道def是ADef。
- 这给了我错误:baseb=new a();(无法隐式转换类型A' to base')
- 因为同样的原因,Collection