9

私は拡張メソッドに恋をし始めていますが、特定のオブジェクト型だけに 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);
}

ありがとうございました。

4

5 に答える 5

13

2 つの拡張メソッドを作成するのはどうでしょうか。

public static void AddPhoneNumber(this Contact contact, PhoneType type);

public static void AddPhoneNumber(this Person person, PhoneType type);

私にはきれいに見えます。

両者の間に共通のコードがある場合は、それを別のメソッドに抽出します。

于 2009-02-05T10:31:20.537 に答える
7

共通のインターフェイスを作成ContactしてPerson実装し、たとえばIContactWithPhoneNumbers、「このインターフェイス用」の拡張メソッドを記述します。

public interface IContactWithPhoneNumbers {}
public class Contact : IContactWithPhoneNumbers {}
public class Person : IContactWithPhoneNumbers {}
public static void AddPhoneNumber(this IContactWithPhoneNumbers obj) {}
于 2009-02-05T10:27:31.637 に答える
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);
    }
}

ただし、基になるオブジェクトを制御できる場合のベストプラクティスは、共通のインターフェイスを実装することだと思います。

于 2009-02-05T10:37:32.600 に答える
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' は lock ステートメントで必要な参照型ではない」ため使用できないため、何らかの値を返す必要がある場合があります。

T 型の Phones メソッドを解決できないというエラーが表示される場合は、次のようにします。

型 T を取り、何も返さず、 action を実行する関数デリゲートを渡し((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 メソッドには、Phones() メソッドを持つように定義したばかりの IPhoneable インターフェイスから継承するという要件がありTます。

ジェネリック コレクションの C# 拡張メソッドも参照してください。

于 2009-07-02T16:44:13.823 に答える