2010-05-20 2 views
0

Это немного запутанный вопрос, надеюсь, я смогу его прояснить.Передача производных объектов в конструкцию

Я нахожу, что это может быть невозможно, но я пытаюсь понять, есть ли у кого-нибудь решение.

У меня есть четыре класса, два являются основными классами и два являются теми основными классы расширены:

extUser Расширяет coreUser
extSecurity Расширяет coreSecurity

В конструкторе для coreUser у вас есть это:

public coreUser(string id, ref coreSecurity cs) 

При попытке расширения coreUser вы бы хотели е это:

public extUser(string id ref extSecurity es) : base(id, ref es) 

Это терпит неудачу, потому что эс имеет тип, extSecurity и базовый класс ожидает тип coreSecurity. Я все равно не нашел это, чтобы позволить мне переопределить этот базовый класс в C#. В VB это работает отлично.

В качестве примечания, я, ради этого вопроса, 100% не смог внести изменения в основные классы.

Идеи?

ответ

2

Это связано с тем, что параметры для параметров ref должны иметь точно того же типа, что и параметр, а не только тот, у которого есть доступное преобразование.

Действительно ли, действительно необходимо ref часть? Создание конструктора параметра ref довольно необычно. Вы уверены, что это не просто путаница в отношении parameter passing mechanisms? Я знаю, вы сказали, что не можете изменить «основные» типы, но вы должны хотя бы взглянуть на их изменение в какой-то момент в будущем, если они действительно не используют эту функцию «ref». Если они являются использования «реф», то это имеет смысл, что это не разрешено ... coreUser конструктор может выглядеть следующим образом:

public coreUser(string id, ref coreSecurity cs) 
{ 
    coreSecurity = new coreSecurity(); 
} 

что бы запутать extUser конструктор, не так ли? es затем обратиться к объекту, который не был extSecurity ...

(наряду с подобными «это странно» линии - ваши типы действительно camelCased Эти конвенции .NET являются для типов, которые будут PascalCased ...?)

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

public extUser(string id, ref coreSecurity cs) : base(id, ref cs) 
{ 
    extSecurity es = (extSecurity) cs; 
    // Use es here 
} 

Конечно, это вызовет исключение, если cs относится к объекту, который не является extSecurity к моменту возврата базового конструктора ...

0

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

0

ref Используется для управления типом значения (например, ссылки, структуры или цепочки и т. Д.). Это само по себе показывает огромное злоупотребление конструктором (Constructor does real work, это java, но также применяется). Конструкторы должны построить объект, для которого вам никогда не нужен параметр ref. Я знаю, что это на самом деле не отвечает на ваш вопрос, но ваш код серьезно испорчен.

исх ключевое слово

Вообще говорят, реф ключевое слово позволяет аргументы, которые будут передаваться по ссылке. Это означает, что изменения в аргументах будут отображаться вне области действия метода.

Пример 1: пропускании исх INT

public class Test 
{ 
    public void TestMethod (ref int input) 
    { 
    input = 2; 
    } 
    public void Run() 
    { 
    int testVar = 1; 
    TestMethod(ref testVar); 
    //testVar is now 2 
    } 
} 

Пример 2: Передача строки реф Обычно, если вы передать строку (или любой другой тип ссылки), в к способу, вы не может изменить объект сам.

public class Test 
{ 
    public void TestMethod (ref string input) 
    { 
    input = "changed"; 
    } 
    public void Run() 
    { 
    string testVar = "original"; 
    TestMethod(ref testVar); 
    //testVar is now "changed" 
    } 
} 

С помощью аргумента ref он позволяет изменять сам объект, а не только его поля и свойства. Аргумент ref в ссылочном типе позволяет вам самому изменять ссылку (назначая ему новый объект), а не только содержимое ссылки (см. msdn).

+0

ref также может использоваться с ссылочными типами. Эти два понятия в основном ортогональны. См., Например, Dictionary.TryGetValue, имея в виду, что это очень похоже на ref. –

+0

Да, его можно использовать и с ссылочными типами, как я писал (сама ссылка является типом значения, поэтому ссылочный ссылочный тип ref является ссылкой на ссылку), что позволяет вам назначать новый объект параметру, и это будут отражаться вне метода. Параметры вывода в этом случае являются чем-то другим. – Femaref

+0

Пока я вижу, что вы пытаетесь сказать, ИМО, вызывающая ссылку, тип значения очень запутан. Как я могу получить объект Type, связанный с этим предполагаемым типом? Если кто-то не понимает, что означает ref, я думаю, что ваш ответ скорее смутит, чем осветит. Я подозреваю, что ref здесь не нужен, но не обязательно потому, что конструктор делает слишком много работы. –

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