我开始爱上扩展方法,但我只是不知道如何为确定的对象类型创建EM。
我有例如:
public static void AddPhoneNumberToContact(this Contact contact, PhoneType type, String number)
{
lock (contact)
{
PhoneRow pr = PhoneRow.CreateNew();
pr.SetDefaults();
pr.PtypeIdx = type;
pr.PhoneNumber = number;
contact.Phones.Add(pr);
pr = null;
}
}
我的问题是我想在Person对象中也有这个方法,这就是我命名
的原因AddPhoneNumberToContact
AddPhoneNumberToPerson
有没有办法让AddPhoneNumber处理提供的对象?
或解决方案是
public static void AddPhoneNumber(this object contact, ...
{
...
if(typeof(Contact) == contact)
((Contact)contact).Phones.Add(pr);
else if(typeof(Person) == contact)
((Person)contact).Phones.Add(pr);
}
谢谢。
答案 0 :(得分:11)
如何编写两种扩展方法:
public static void AddPhoneNumber(this Contact contact, PhoneType type);
和
public static void AddPhoneNumber(this Person person, PhoneType type);
对我来说看起来更干净。
如果两者之间存在一些共同的代码,请将其提取到单独的方法中。
答案 1 :(得分:7)
让Contact
和Person
实现通用接口 - 比如IContactWithPhoneNumbers
- 然后为此接口编写扩展方法。
public interface IContactWithPhoneNumbers {}
public class Contact : IContactWithPhoneNumbers {}
public class Person : IContactWithPhoneNumbers {}
public static void AddPhoneNumber(this IContactWithPhoneNumbers obj) {}
答案 2 :(得分:2)
阅读您的评论(对象来自SDK并且不可编辑)。我可能会做这样的事情:
public class Util
{
//common util method
public static void AddPhoneNumber(object obj, string phoneNumber)
{
if(obj is Contact)
((Contact)contact).Phones.Add(phoneNumber);
else if(obj is Person)
((Person)contact).Phones.Add(phoneNumber);
}
//extension method for Person
public static void AddPhoneNumber(this Person p, string phoneNumber)
{
AddPhoneNumber((object)p, phoneNumber);
}
//extension method for Contact
public static void AddPhoneNumber(this Contact c, string phoneNumber)
{
AddPhoneNumber((object)c, phoneNumber);
}
}
我确实认为,当您控制底层对象时,最好的做法是实现一个通用接口。
答案 3 :(得分:0)
您可以将扩展方法设为通用,例如:
public static void AddPhoneNumberToContact<T>(
this T contact,
PhoneType type,
String number
)
{
PhoneRow pr = PhoneRow.CreateNew();
pr.SetDefaults();
pr.PtypeIdx = type;
pr.PhoneNumber = number;
((T)contact).Phones.Add(pr);
pr = null;
}
您将无法使用lock
,因为“'T'不是锁定语句所要求的引用类型”,因此您可能必须返回一些值。
如果它抱怨无法解决类型T上的电话方法,您可以:
传递一些{T}类型的function delegate,不返回任何内容,然后执行((T)contact).Phones.Add(pr);
行动。
或者您可以创建如下界面:
public interface IPhoneable
{
IList<Phone> Phones();
}
然后,一旦拥有该界面,就可以将以下内容添加到通用扩展方法中:
public static void AddPhoneNumberToContact<T>(
this T contact,
PhoneType type,
String number
) where T : IPhoneable {...}
在这里,T
仍然是一个泛型类型,但现在你的AddPhoneNumberToContact方法要求,无论T
是什么,它都从IPhoneable接口继承,你刚才定义了它的电话(方法。
答案 4 :(得分:0)
如果你不能改变Person和Contact,你可以创建它们的子类,让它们实现公共接口。
在扩展方法中,将公共接口声明为参数:
{{1}}