Важно отметить, что ClassB
и ShimClassB
не имеют отношения класса, производного от базового класса. Таким образом, броски, которые вы делаете, могут быть не совсем такими, как вы ожидаете. Вы видите, что неявные преобразования работают из-за пользовательских преобразований, предоставленных Microsoft.Fakes.
Ваш ShimClassB
наследуется от ShimBase<T>
, где T равно ClassB
. Этот класс имеет метод, который вводит определяемое пользователем неявное преобразование между ShimClassB
и ClassB
.
public static implicit operator T(ShimBase<T> shim)
Когда вы пытаетесь сделать.
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}
у вас не может быть приведения к ClassB
, так как между object
и ClassB
не определено преобразование.
Из спецификации языка программирования С# 6.2.4 Явные преобразования ссылок:
Для успешного явного преобразования ссылки во время выполнения значение исходного операнда должно быть нулевым или фактический тип объекта, на который ссылается исходный операнд, должен быть типом, который может быть преобразован в целевой тип с помощью неявной ссылки. преобразование (§6.1.6) или преобразование бокса (§6.1.7). Если явное преобразование ссылки не удается, создается исключение System.InvalidCastException.
Вы обнаружите, что если бы ваш код имел промежуточное приведение, он больше не выдавал бы InvalidCastException
, однако это не окончательное решение, поскольку вы не хотите приведения к Shim в своем конструкторе:
public ClassA(object someInstance)
{
PropertyB = (ClassB)(ShimClassB)someInstance;
}
Чтобы решить эту проблему. Я бы посоветовал изменить ваш конструктор ClassA так, чтобы он был типизирован и не принимал object
, когда вы передаете свой shimClassB в этот конструктор, вы обнаружите, что будет использоваться определяемое пользователем неявное преобразование:
// The user-defined implicit conversion takes care of this for us
ClassA(shimClassB);
public ClassA(ClassB someInstance)
{
PropertyB = someInstance;
}
или если вы хотите сохранить свой конструктор как есть:
ClassA((ClassB)shimClassB);
public ClassA(object someInstance)
{
PropertyB = (ClassB)someInstance;
}
person
Martin
schedule
11.03.2014