2009-02-05 4 views
8

저는 Extension Methods와 사랑에 빠지기 시작했습니다. 그러나 나는 결정적인 Object 타입에 대해서만 EM을 만드는 방법을 모른다. 방법이 거기에있다제 3 자 SDK의 여러 비 관련 유형에 공통 확장 메소드를 적용하려면 어떻게해야합니까?

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

그런 자물쇠로 조심. AddPhoneNumberToContact의 호출자가 잠금 및 잠금을 인식하지 못하면 호출하기 전에 자신에게 연락하여 교착 상태가 보장됩니다. 일반적으로 개인 객체를 잠급니다. 확장 방법을 사용하면 이것이 불가능합니다. – Mendelt

+0

게시물을 수정하여 해당 클래스를 수정할 수 없음을 명확히하십시오. 또한 상속 계층을 포함합니다. –

+0

@Anton Gogolev 바로 제목에 있습니다! "타사 SDK" – balexandre

답변

11

방법이 확장 메서드를 작성하는 방법에 대한 :

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

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

나에게 청소기 보이는

.

두 코드 사이에 공통 코드가있는 경우이를 별도의 방법으로 추출하십시오.

+1

어리석은 나는 때때로 일 수있다 !!! :) 감사합니다 – balexandre

+0

같은 이름을 가진 여러 함수에 대한 모든 것을 잊어 버렸습니다 : '((그리고 나는 그것을 많이 사용합니다!하지만 내게 새로운 것이 었습니다, ExMethods (!)) – balexandre

7

ContactPerson이 공통 인터페이스 (예 : IContactWithPhoneNumbers)를 구현 한 다음 "이 인터페이스 용"확장 메서드를 작성하십시오.

public interface IContactWithPhoneNumbers {} 
public class Contact : IContactWithPhoneNumbers {} 
public class Person : IContactWithPhoneNumbers {} 
public static void AddPhoneNumber(this IContactWithPhoneNumbers obj) {} 
+0

연락처 및 사람이 보호되어 있으므로 SDK에서 가져 왔습니다. – balexandre

1

의견을 읽고 있습니다 (개체는 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); 
    } 
} 

가 그래도 가장 좋은 방법을 생각 : 아마 같은 것을 할 것입니다.

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; 
} 
" 'T'는 잠금 문에서 요구하는 참조 형식이 아닌"때문에 당신은 lock을 사용할 수 없습니다

, 당신 때문에 어떤 가치를 돌려 주어야 할지도 모릅니다.

그것에 대해 타입 T에 전화 방법을 해결할 수 없다는 불만을 경우, 수 : T 형을 아무 것도 반환하지 않으며, 작업 ((T)contact).Phones.Add(pr);을 수행 할 몇 가지 function delegate

패스.

또는 당신은 다음과 같은 인터페이스를 만들 수 있습니다, 그리고

public interface IPhoneable 
{ 
    IList<Phone> Phones(); 
} 

을 당신이 인터페이스를 가지고 일단 당신이 당신의 일반적인 확장 메서드에 다음을 추가 할 수 있습니다 : 여기

public static void AddPhoneNumberToContact<T>(
    this T contact, 
    PhoneType type, 
    String number 
) where T : IPhoneable {...} 

, T 여전히 제네릭 유형이지만, 이제는 AddPhoneNumberToContact 메소드에 어떤 T이든간에, Phones() 메소드를 갖기 위해 방금 정의한 IPhoneable 인터페이스를 상속해야한다는 요구 사항이 있습니다.

도 참조하십시오. C# Extension Method for Generic Collections.

+0

나는 이것을 더 잘 보살펴줍니다. 통찰력. – balexandre

0

개인 및 연락처를 변경할 수없는 경우 해당 하위 클래스를 만들어 공통 인터페이스를 구현할 수 있습니다. 확장 방법에

당신은 매개 변수로 공통 인터페이스를 선언 :

using System; 
using System.Collections.Generic; 

public class Program 
{ 
    public static void Main() 
    { 
     var p = new MyPerson(); 
     p.Name = "test"; 
     p.AddPhonenumber("555-2356"); 
     Console.WriteLine(string.Join(", ", p.Phonenumber)); 

     var c = new MyContact(); 
     c.Name = "contact"; 
     c.AddPhonenumber("222-235"); 
     Console.WriteLine(string.Join(", ", c.Phonenumber)); 
    } 
} 


public class Contact 
{ 
    public Contact() { 
     this.Phonenumber = new List<string>(); 
    } 
    public string Name { get; set; } 
    public List<string> Phonenumber { get; set; } 
    public string Foo { get; set; } 
} 
public class Person 
{ 
    public Person() { 
     this.Phonenumber = new List<string>(); 
    } 
    public string Name { get; set; } 
    public List<string> Phonenumber { get; set; } 
    public string Bar { get; set; } 
} 

public class MyContact: Contact, IType { 
} 

public class MyPerson: Person, IType { 
} 


public static class Extensions { 
    public static void AddPhonenumber(this IType type, string number){ 
     type.Phonenumber.Add(number); 
    } 
} 

public interface IType { 
    string Name {get; set; } 
    List<string> Phonenumber {get; set;} 
} 
관련 문제