Добавление ссылки на сборку требует также ссылки на базовую сборку - PullRequest
2 голосов
/ 06 апреля 2010

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

Когда я добавляю ссылку на ребенка, Visula studio также требует, чтобы ссылка была добавлена ​​к родителю.

Почему это так и как я могу предотвратить это, не теряя никакой функциональности?

Ответы [ 2 ]

2 голосов
/ 07 декабря 2012

То, что вы описываете, частично возможно. Вы можете избавить их от необходимости явно ссылаться на скрытую сборку, но эта сборка все равно будет извлечена во время компиляции и потребуется во время выполнения.

Допустим, у вас определены следующие классы:

// in assembly 1:
public class A
{
    public virtual void Foo() { }
}

// and in assembly 2:

// requires explicit reference to assembly 1 to use
public class B : A
{
    public override void Foo() { }
    public A Value { get; set; }
    public void Foo(A value) { }
}
// has implicit reference to assembly 1, but end user can ignore
public class C
{
    private A Value { get; set; }
    internal void Foo(A value) { }
    protected internal A Bar() { return new A(); }
}
// usable at runtime even if assembly 1 is missing, as long as you don't call Foo()
public class D
{
    public void Foo() { A blah = new A(); }
    public void Bar() { }
}

Если конечный пользователь использует класс B, ему потребуется явная ссылка на сборку 1. Поскольку A является частью открытого интерфейса B, для использования B необходимо знать об A. Есть 3 различных открытых ссылки на A, и любой из них потребует знания о A, чтобы использовать B.

Однако класс C делает ссылки на A, но все ссылки являются частными / внутренними / локальными. Поскольку каждая ссылка на A скрыта извне, конечный пользователь не обязан явно знать о сборке 1. Она все еще потребуется во время выполнения, но вам не нужно добавлять ее в качестве ссылки, это косвенная ссылка .

И если конечный пользователь использует класс D, даже не используя B или C, сборка 1 будет загружена только при вызове D.Foo (), у которого есть локальная переменная типа A. Вы можете фактически использовать D.Bar () свободно, даже если сборка 1 полностью отсутствует во время выполнения. Хотя если вы вызовете D.Foo () и сборка 1 отсутствует, вы получите исключение.

0 голосов
/ 13 июля 2010

В C / C ++ определение класса присутствует в заголовочном файле .h. Это дает вам возможность ссылаться на информацию о классе (при необходимости, например, когда вы хотите наследовать от этого класса) без необходимости в исходном файле с информацией о реализации. Недостатком является дублирование кода (реализация в файле .cpp должна повторять большую часть информации в файле .h).

В мире .NET дизайн отличается: сборка содержит как код класса (байт-код CLR), так и все метаданные (имя класса, информацию о его членах и т. Д.), Необходимые, например, для: наследовать от этого класса.

Следствием такой конструкции является то, что для использования класса, определенного в сборке A, который наследуется от класса в сборке B, для .NET необходимы сборки A и B. Или, в более общем смысле: если вы используете что-либо из данной сборки (класс, перечисление, структура), прямо или косвенно, вам нужно ссылаться на эту сборку.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...