Метод расширения и явное литье
-
25-10-2019 - |
Вопрос
Я использую класс из некоторой сборки (исходный код недоступен), поэтому невозможно изменить код их, мне нужно добавить метод расширения для явного литера -оператора, есть ли способ этого? (Я пытался добавить в качестве регулярного метода расширения, но без успеха)
public static explicit operator MembershipUser(this MembershipUser membership, User user)
{
return new MembershipUser("SimplyMembershipProvider", user.UserName, user.UserId, user.Email, null, null, user.IsApproved, user.IsLocked,
user.CreateDate, user.LastLoginDate, user.LastActivityDate, user.CreateDate, DateTime.MinValue);
}
Как я могу решить это?
Решение
Вы не можете перегружать операторов с помощью методов расширения.
Лучше всего можно сделать с помощью метода расширения:
public static MembershipUser ConvertToMembershipUser(this User user)
{
return new MembershipUser("SimplyMembershipProvider",
user.UserName,
user.UserId,
user.Email,
null,
null,
user.IsApproved,
user.IsLocked,
user.CreateDate,
user.LastLoginDate,
user.LastActivityDate,
user.CreateDate,
DateTime.MinValue);
}
MembershipUser membershipUser = aUser.ConvertToMembershipUser();
Другие советы
Как говорили другие, вы не можете перегружать операторов, используя методы расширения, но простой метод расширения все равно будет полезен:
public static MembershipUser ToMembershipUser(this User user)
{
return new MembershipUser("SimplyMembershipProvider",
user.UserName, user.UserId, user.Email, null, null,
user.IsApproved, user.IsLocked, user.CreateDate,
user.LastLoginDate, user.LastActivityDate, user.CreateDate,
DateTime.MinValue);
}
Тогда просто используйте его как:
User user = ...;
MembershipUser membershipUser = user.ToMembershipUser();
Лично я нахожу это более ясным, чем явное использование явного преобразования - я очень редко использую перегрузку оператора. В частности, учитывая, что классы определенно звук Связанный, наивный пользователь может ожидать этого кода:
User user = ...;
MembershipUser membershipUser = (MembershipUser) user;
... чтобы быть нормальным переоборудованием, ожидая MembershipUser
быть классом, полученным из User
. Анкет Это важно с точки зрения идентичности объекта - если это мы Дело, это не изменит вовлеченный объект (и изменения в объекте, на котором упоминается user
все еще был бы виден через membershipUser
).
Создание а ToMembershipUser
Метод проясняет, что вы преобразуете из одной формы в новый объект другого типа. Все ИМО, конечно :)
Нет, вы не можете добавить преобразование расширения.
Явные или неявные преобразования могут быть определены только в том случае, если вы управляете исходным кодом для одного из задействованных типов. В вашем случае вы можете управлять либо MembershipUser
или же User
, вам не нужно контролировать оба. Но ты должен контролировать один.
Если вы не контролируете ни того, ни другого, вам просто нужно определить конверсию в методе какого -либо другого класса, чья работа заключается в том, чтобы контролировать такое преобразование.
class UserConverter
{
public MembershipUser ConvertFrom(User user)
{
return ...
}
}
Не сказать, что это хорошая практика (прочитайте другие ответы за то, почему вы не должны этого хотеть, но если классы не запечатаны, это возможно, просто не используйте методы расширения).
По сути, вы можете создать суррогатный класс, наследующий пользователя, который определяет оператора кастинга, что -то вроде:
class UserSurrogate : User
{
public static explicit operator UserSurrogate(MemberShipUser other)
{
return new UserSurrogate() { Name = other.Name };
}
}
class User
{
public string Name { get; set; }
}
class MemberShipUser
{
public string Name { get; set; }
}