2013-03-14 3 views
1

У меня есть проект, который использует Autofac для создания экземпляров объектовПочему мой унаследованный класс не скрывает мой метод базового класса?

builder.RegisterType<AbcWebWorkContext>().As<IWorkContext>().InstancePerHttpRequest(); 

Это AbcWebWorkContext подкласс WebWorkContext:

public partial class AbcWebWorkContext : WebWorkContext 

В моей AbcWebWorkContext я хотел бы скрыть метод и свойство от родительский класс

protected new Customer GetCurrentCustomer(){ //do stuff } 
new public Customer CurrentCustomer { //do studd } 

Но когда кто-то звонит

_workContext.CurrentCustomer 

Вызывается базовое свойство класса. Если я позвоню так

((AbcWebWorkContext) _workContext).CurrentCustomer 

это работает.

Я хотел бы знать, почему я не могу скрыть родительский метод. Я не могу изменить вызываемый класс, потому что он находится в ядре NopCommerce, который я бы не хотел менять.

Почему это не скрывает метод?

Базовый класс декларация методов:

protected Customer GetCurrentCustomer() { // do stuff } 
public Customer CurrentCustomer{ // do stuff } 

GetType() вызова на выходе _workcontext воли

{Name = "AbcWebWorkContext" FullName = "Nop.Web.Framework.AbcWebWorkContext"}

Иерархия тип IWorkContext (интерфейс) « WebWorkContext « AbcWebWorkContext

_workContext объявлен как IWorkContext и Autofac создает экземпляр как AbcWebWorkContext (как показано выше)

+0

Как был объявлен метод в базовом классе? – pickypg

+0

@pickypg добавил его к вопросу – JSBach

+0

http://stackoverflow.com/questions/1853896/is-it-possible-to-override-a-non-virtual-method – pickypg

ответ

3

new ключевого слова означает, что метод кожевенного подкласс базовых класс-х CurrentCustomer вместо переопределения, так WebWorkContext.CurrentCustomer совершенно другой метод, чем AbcWebWorkContext.CurrentCustomer.

Вы должны объявить метод базового класса, как

virtual Customer CurrentCustomer { ... } 

И метод подкласса

override Customer CurrentCustomer { ... } 

Я предлагаю вам прочитать больше о polymorphism in c#.

Если методы вы используете фактически определены в интерфейсе, IWebWorkContext, вы просто инкапсулировать базовый класс, а не наследовать от него, как это:

class AbcWebWorkContext : IWebWorkContext 
{ 
    private WebWorkerContext _inner = new WebWorkerContext(); 

    public Customer CurrentCustomer { ... } 
} 

Если вы не можете сделать базу класса, вы должны сделать что-то гораздо менее элегантное, например отражение:

var prop = _workContext.GetType().GetProperty("CurrentCustomer"); 
var value = (Customer)prop.GetValue(_workContext, new object[0]); 
+0

Я не могу, потому что я не могу изменить исходный код ядра. вызов gettype() в _workcontext будет выводиться {Name = "AbcWebWorkContext" FullName = "Nop.Web.Framework.AbcWebWorkContext"}. Поэтому следует вызывать версию метода AbcWebWorkContext. правильно? – JSBach

+0

Извините, у меня нет ни кода вызывающего абонента, ни кода вызываемого абонента. Я пытаюсь перехватить вызов, чтобы внести изменения в его поведение, не меняя код ядра. – JSBach

+0

@Oscar Тогда, боюсь, повторное внедрение интерфейса, вероятно, является вашим единственным вариантом. –

2

Я не уверен, если я получил ваши вопросы правильно, но я думаю, что нужно добавить модификатор virtual к метод в базовом классе и добавьте модификатор override к методу в подклассе.

Узнайте больше на MSDN

+0

Да, это будет переопределять метод, но я не может добавить «виртуальный», потому что я не могу изменить исходный код – JSBach

+0

@Oscar, C# не похож на Java, методы по умолчанию не являются виртуальными. Если вы не можете изменить базовый класс, чтобы сделать метод виртуальным, вы не можете переопределить его в дочернем классе. У вас есть возможность * скрывать * это, но, как вы нашли, это не так полезно, кроме как через собственную ссылку производного класса. –

+0

Да, мое плохое. Я написал «переопределить» в названии этого вопроса. Я имел в виду скрыть. Я отредактирую его. вызов gettype() в _workcontext выведет {Name = "AbcWebWorkContext" FullName = "Nop.Web.Framework.AbcWebWorkContext"}. Поэтому следует вызывать версию метода AbcWebWorkContext. правильно? – JSBach

Смежные вопросы