Вы можете попробовать использовать WebDriver с Windows Insider для тестирования веб-проектов с MS Edge.
WebDriver - это новый стандарт, с помощью которого веб-разработчики могут писать тесты для автоматизации веб-браузеров для тестирования сайтов. Он обеспечивает программируемое дистанционное управление для разработки сложных пользовательских сценариев и автоматического запуска их на вашем веб-сайте в браузере.
Ссылка:
Внедрение автоматизированного тестирования в Microsoft Edge через WebDriver
Другие полезные ссылки:
Автоматическое тестирование браузера в Microsoft Edge , Firefox и Chrome бесплатно.
Если типы идентичны, и Вы управляете исходными классами, можно определить оператор преобразования в классе и любую функцию, которая берет a Rate.Address
также автоматически возьмет a Ship.Address
. Например:
namespace Rate {
class Address {
string Street;
string City;
// ...
public static implicit operator Ship.Address(Rate.Address addr) {
Ship.Address ret;
ret.Street = addr.Street;
ret.City = addr.City;
// ...
return ret;
}
}
}
Мой C# немного ржав, но я надеюсь, что Вы получаете идею.
Таким образом, вот то, как я реализовал неявные операторы преобразования с помощью отражения. SvcUtil создает частичные классы, таким образом, я добавил неявный оператор преобразования для каждого направления преобразования так в клиентском коде, можно просто ввести Type1 = Type2
.
В этом отрывке WebAuthenticationCredentials является свойством WebAuthenticationDetails поэтому при итерации свойств исходного объекта, если типы не являются тем же (созданным-ins), он проверяет название типов (без пространства имен) и рекурсивно вызывает функцию копии с теми свойствами.
internal class ReflectionCopy
{
public static ToType Copy<ToType>(object from) where ToType : new()
{
return (ToType)Copy(typeof(ToType), from);
}
public static object Copy(Type totype, object from)
{
object to = Activator.CreateInstance(totype);
PropertyInfo[] tpis = totype.GetProperties(BindingFlags.Public | BindingFlags.Instance);
PropertyInfo[] fpis = from.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
// Go through each property on the "to" object
Array.ForEach(tpis, tpi =>
{
// Find a matching property by name on the "from" object
PropertyInfo fpi = Array.Find(fpis, pi => pi.Name == tpi.Name);
if (fpi != null)
{
// Do the source and destination have identical types (built-ins)?
if (fpi.PropertyType == tpi.PropertyType)
{
// Transfer the value
tpi.SetValue(to, fpi.GetValue(from, null), null);
}
else
{
// If type names are the same (ignoring namespace) copy them recursively
if (fpi.PropertyType.Name == tpi.PropertyType.Name)
tpi.SetValue(to, Copy(fpi.PropertyType, tpi.GetValue(from, null)), null);
}
}
});
return to;
}
}
namespace Rate
{
partial class WebAuthenticationDetail
{
public static implicit operator Ship.WebAuthenticationDetail(WebAuthenticationDetail from)
{
return ReflectionCopy.Copy<Ship.WebAuthenticationDetail>(from);
}
}
partial class WebAuthenticationCredential
{
public static implicit operator Ship.WebAuthenticationCredential(WebAuthenticationCredential from)
{
return ReflectionCopy.Copy<Ship.WebAuthenticationCredential>(from);
}
}
}
namespace Ship
{
partial class WebAuthenticationDetail
{
public static implicit operator Rate.WebAuthenticationDetail(WebAuthenticationDetail from)
{
return ReflectionCopy.Copy<Rate.WebAuthenticationDetail>(from);
}
}
partial class WebAuthenticationCredential
{
public static implicit operator Rate.WebAuthenticationCredential(WebAuthenticationCredential from)
{
return ReflectionCopy.Copy<Rate.WebAuthenticationCredential>(from);
}
}
}
Вы могли использовать оператор, перегружающийся путем создания собственной реализации Адреса, или использовать один из стабильных типов как свойство
один пример: Address1 и Address2 ниже был бы Ваш Уровень. Адрес и Поставка. Адрес соответственно
class Address1
{
public string name = "Address1";
}
class Address2
{
public string name = "Address2";
}
class GenericAddress
{
public string name = "GenericAddress";
public static implicit operator GenericAddress(Address1 a)
{
GenericAddress p = new GenericAddress(); p.name = a.name; return p;
}
public static implicit operator GenericAddress(Address2 a)
{
GenericAddress p = new GenericAddress(); p.name = a.name; return p;
}
}
class Program
{
static void Main(string[] args)
{
PrintName(new Address1());//prints address1
PrintName(new Address2());//prints address2
}
static void PrintName(GenericAddress a)
{
Console.WriteLine(a.name);
}
}
Править: подход совпадает с сообщением выше, реализация находится в отдельном классе, это - все
Это - сгенерированные классы, определенные как "неравнодушные"? Если так, Вы могли расширить их в другом файле и извлечь интерфейс и позволить ему быть реализованным всеми Классами адресов.