2014-09-19 2 views
2

확장 메서드를 클래스의 생성자에 인수로 전달하고 해당 클래스의 메서드에서 해당 확장을 확장으로 사용하려면 어떻게해야합니까?메서드 확장을 인수로 전달

예를 들어이는 IEnumerable을 확장 메서드가 들어있는 파일입니다

namespace System.Collections.Generic 
{ 
    public static partial class IEnumerableMethodExtensions 
    { 
     /// <summary> 
     /// Used by IsImageFile to determine if a file is a graphic type 
     /// we care about. (Not an Extension Method, just a helper method) 
     /// </summary> 
     public static string[] GraphicFileExtensions = new string[] { ".png", ".bmp", ".gif", ".jpg", ".jpeg" }; 

     /// <summary> 
     /// Method Extension - specifies that FileInfo IEnumerable should only 
     /// return files whose extension matches one in GraphicFileExtensions[]. 
     /// </summary> 
     /// <param name="files"></param> 
     /// <returns></returns> 
     public static IEnumerable<FileInfo> IsImageFile(this IEnumerable<FileInfo> files) 
     { 
      foreach (FileInfo file in files) 
      { 
      string ext = file.Extension.ToLower(); 
      if (GraphicFileExtensions.Contains(ext)) 
       yield return file; 
     } 
    } 
} 

을}

나는이 객체에 생성자에 인수로() IsImageFile을 통과 할 수 있도록하려면

, 그래서 해당 클래스의 메서드는 메서드 확장으로 IsImageFile을 사용할 수 있습니다.

public class MainFileInfoSource 
{ 
    public MainFileInfoSource(List<DirectoryInfo> Directories, 
       ENUMERABLE_METHOD_EXTENSION_FILE_FILTER TheMethodExtension) 
    { 
     _myFilterMethodExtension = TheMethodExtension; 
     _directories = Directories; 

     initializeFileInfoList(); 
    } 

    ... 

    /// <summary> 
    /// Initializes the Files list. 
    /// </summary> 
    private void initializeFileInfoList() 
    { 
    ... 
     for (int i = 0; i < _directories.Count; i++) 
     { 
      iEnumerableFileInfo = new[] { _directories[i] }.Traverse(dir => 
      getDirectoryInfosWithoutThrowing(dir)).SelectMany(dir => 
      getFileInfosWithoutThrowing(dir)._myFilterMethodExtension()); 
+1

http://stackoverflow.com/questions/1016033/extension-methods-defined-on-value-types-cannot-be-used-to-create-delegates-wh – AlexanderBrevig

+0

@AlexanderBrevig 당신이 나를 도울 수 그 질문/대답의 어떤 부분이 나의 테이크 아웃인지 이해하시오. 외관상으로는 나는 연결을보기에는 충분히 똑똑하지 않다. –

+0

정적 메서드 호출이 컴파일 타임에 컴파일되므로이를 수행 할 수 없습니다. 실제 목표가 무엇인지 설명하면 잘 보이는 접근 방식을 찾는 데 도움이 될 수 있습니다 (구현 방법을 찾기 위해 서비스 로케이터 패턴을 사용하여 구현 된 확장 메소드 등). –

답변

3

확장자 메서드를 클래스의 생성자에 인수로 전달할 수있는 방법은 무엇입니까?

찾고있는 서명과 일치하는 대리인을 만듭니다. 예를 들어, Func<IEnumerable<FileInfo>, IEnumerable<FileInfo>>은 제공된 경우 작동합니다. ...

var source = new MainFileInfoSource(directories, FileFilterExtensions.IsAwesome); 
var source2 = new MainFileInfoSource(directories, f => f.IsAwesome()); 

, 그 클래스의 메소드가이 경우에 당신이 정적 위치를 사용하거나 람다 표현식을 사용하는 방법을 확인해야합니다 어느 쪽이든

public MainFileInfoSource(List<DirectoryInfo> Directories, 
      Func<IEnumerable<FileInfo>, IEnumerable<FileInfo>> FilterMethod) 

주 확장 기능을 확장 기능으로 사용 하시겠습니까?

이것은 수행 할 수 없습니다. 확장 메서드는 특수 구문 설탕 일 뿐이며 사용 방법에 대한 많은 규칙을 가지고 있습니다. 이 정보는 확장 메서드에서 대리자를 만들 때 전송되지 않습니다. 따라서 대리인을 일반적인 메서드로 호출해야합니다.

 iEnumerableFileInfo = new[] { _directories[i] } 
      .Traverse(dir => getDirectoryInfosWithoutThrowing(dir)) 
      .SelectMany(dir => _myFilterMethod(getFileInfosWithoutThrowing(dir))); 
+0

감사합니다. 이것은 효과가있다. IEnumerable 메서드 확장으로 표현하고 싶었습니다. 다른 방법으로는 눈이 멀었습니다. 너무 나쁘지 만, 나는 메소드 확장을 쌓는 것을 좋아한다.:-) –

+0

나는 또한 "일반"IEnumerable 필터 확장 메서드를 작성할 수 있다고 가정합니다.이 메서드는 인수로 필터 문자열을 가져 와서 해당 필터 문자열을 내 생성자로 전달합니다. 만약 내가 진정으로 메소드 확장을 원한다면. –

0

잘 작동하지 않습니까?

public class MainFileInfoSource 
{ 
    public MainFileInfoSource(List<DirectoryInfo> Directories, 
     Func<IEnumerable<FileInfo>, IEnumerable<FileInfo>> TheMethodExtension) 
    { 

    } 
} 

new MainFileInfoSource(null, IEnumerableMethodExtensions.IsImageFile); 

?

+0

Valentin, 나는 사실 Intellisense를 통해 getFileInfosWithoutThrowing()에서 점 뒤에 나타나는 메서드 확장을 얻는 방법을 알 수 없습니다. 나는 Alexander와 StriplingWarrior가 C#이 메서드 확장으로서 대리자를 표현하고 표현하기를 원하지 않는다고 내게 설명해 주었다고 생각한다. –