Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么继承的字段不属于最终类型_C#_Inheritance_Ninject - Fatal编程技术网

C# 为什么继承的字段不属于最终类型

C# 为什么继承的字段不属于最终类型,c#,inheritance,ninject,C#,Inheritance,Ninject,我有以下代码 public abstract class Parent { AnObject AProperty {get; set;} } public class ChildA : Parent { } public class ChildB : Parent { } 当我通过反射访问ChildA的实例时,我看到它的成员AProperty具有DeclaringType等于Parent。可悲的是,我想依靠反思来确定谁是ChildA,谁是ChildB 更多上下文:我实际上试图通过NIn

我有以下代码

public abstract class Parent
{
    AnObject AProperty {get; set;}
}
public class ChildA : Parent { }
public class ChildB : Parent { }
当我通过反射访问
ChildA
的实例时,我看到它的成员AProperty具有
DeclaringType
等于
Parent
。可悲的是,我想依靠反思来确定谁是ChildA,谁是ChildB

更多上下文:我实际上试图通过NInject将
属性
与when子句绑定,以便根据要创建的对象的实际类型进行不同的解析。下面是一个过于简单的例子:

Kernel.Bind<AnObject>().ToConstructor(..).WhenAnyAncestorMatches(c =>
      c.Request.Target.Member
       .DeclaringType.IsAssignableFrom(typeof(ChildA))
Kernel.Bind<AnObject>().ToConstructor(..).WhenAnyAncestorMatches(c =>
      c.Request.Target.Member
       .DeclaringType.IsAssignableFrom(typeof(ChildB))
Kernel.Bind()
c、 Request.Target.Member
.DeclaringType.IsAssignableFrom(typeof(ChildA))
Kernel.Bind().ToConstructor(..).WhenAnceStorMatch(c=>
c、 Request.Target.Member
.DeclaringType.IsAssignableFrom(typeof(ChildB))
问题

  • 我做错什么了吗
  • 我是否必须将
    a属性设置为
    abstract
    ,并在每个
    ChildX
    上覆盖它
  • 当任何取消匹配谓词时,我能否在
    中获取实际类型

如果我没弄错的话,您需要将不同的
对象
注入属性
属性
,具体取决于它注入的子类


提示:如果没有令人信服的理由不这样做,您应该使用构造函数注入而不是属性(或方法)注入


因此,这基本上意味着您需要组合
WhenInjectedTo
WhenAnyAncestorMatches
。您可以查看
WhenInjectedTo
的实现,并使用与
WhenAnceStorMatches
相同的逻辑作为参数,或者您可以使用一些肮脏的技巧将两者结合起来:

var binding = Kernel.Bind<AnObject>().ToConstructor(..);

Func<IRequest, bool> whenInjectedIntoCondition = 
    binding.WhenInjectedInto<int>().BindingConfiguration.Condition;

binding.WhenAnyAncestorMatches(c => whenInjectedIntoCondition(c.Request));
var binding=Kernel.Bind().ToConstructor(…);
当喷射到条件=
binding.WhenInjectedInto().BindingConfiguration.Condition;
binding.WhenAnyAncestorMatches(c=>wheninjectedtocondition(c.Request));


对于构造函数注入,这是有效的,我不能100%确定它是否也适用于属性注入。

我可能遗漏了一些明显的东西,但是你如何根据
a属性通过反射来对
ChildA
ChilB
做出任何类型的决定?正如它在基本类型。使属性
抽象
也不会有帮助,任何
对象
对两者都是可行的,并且C#不允许重写成员中存在类型差异。@中间:否,我正在尝试(让NInject make)断言注入上下文(
C
在上述代码中)在类型为
ChildA
ChildB
的对象中注入
a属性
。我确信它是一个属性(因为
Parent
是抽象的),但NInject将
DeclaringType
视为
父级
,因此无法做出决定,因此我认为基本上您需要的是
当InjectedTo
时,而不是测试它是否被直接注入
ChildA
时,它还应该进入请求树。只需查看反射的代码:声明类型成员(属性)的类型始终是指定它的类(在本例中是父类)。这与ninject“看到”的内容无关,而是与.net如何处理/定义类型和反射有关。因此
member.DeclaringType
无法(永远)帮助您尝试做什么(无论您使用哪个DI容器)。另请参阅,特别是提到“Target、Member、Class”之间区别的部分。为什么不为两者都提供一个接口,您仍然可以使用抽象类。