2013-07-15 73 views
2

在一間非通用類中聲明這兩個方法,它們共享相同的簽名:Func鍵委託聲明的方法

private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
    { 
     return null; 
    } 

    private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
    { 
     return null; 
    } 

如何創建一個表示這些方法簽名的委託?

我似乎無法得到它,我想:

private Func<TypeResolverConfiguration<T>, TypeResolverResult<T>> _typeResolveFunc; 

但明顯這不起作用,因爲類是不通用的,我不能改變的。

感謝

UPDATE

這是多了還是少了什麼,我需要:

public class Manager : ATypeResolver, IManager 
    { 
     private neeedDelegate; 


     public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories) 
     { 
      if (runtimeConfiguration.WhatEver) 
      { 
       neeedDelegate = TryRetrieveFromReusable; 
      } 
      else 
      { 
       neeedDelegate = BuildNew; 
      } 
     } 

     public override TypeResolverResult<T> Resolve<T>() where T : class 
     { 
      //Want to avoid doing this: 

      if (runtimeConfiguration.WhatEver) 
      { 
       TryRetrieveFromReusable(new TypeResolverConfiguration<T>()); 
      } 
      else 
      { 
       BuildNew(new TypeResolverConfiguration<T>()); 
      } 

      //and have just this 

      neeedDelegate<T>(new TypeResolverConfiguration<T>()); 
     } 

     private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
     { 
      return null; 
     } 

     private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class 
     { 
      return null; 
     } 
    } 
+1

在什麼情況下你想使用它?如果什麼都不是通用的,那麼很難擁有泛型類型參數。即使類型不是因爲調用者定義了類型,方法也可以是通用的。但是,除非包含類型是通用的,否則字段和屬性不能是通用的。 – cadrell0

+0

@ cadrell0這些方法是通用的,但類不是通用的,它們有一個已定義的約束:class – Marco

+0

@ cadrell0是的,你是對的,回到開頭。 – Marco

回答

1

更新從我所看到的,這樣的做法應該工作,只要作爲ATypeResolverwhere T : classResolve<T>

public class Manager : ATypeResolver, IManager 
{ 
    private bool tryRetrieveFromReusable; 

    public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories) 
    { 
     this.tryRetrieveFromReusable = runtimeConfiguration.WhatEver; 
    } 
    public override TypeResolverResult<T> Resolve<T>() 
    { 
     var typeResolver = tryRetrieveFromReusable ? (TypeResolver<T>)TryRetrieveFromReusable : BuildNew; 

     return typeResolver(new TypeResolverConfiguration<T>()); 
    } 
} 

這將使用自定義的委託類型(Func像你應該也可以工作):

public delegate TypeResolverResult<T> TypeResolver<T>(
    TypeResolverConfiguration<T> typeResolverConfiguration) where T : class; 

如果你願意,你可以在var typeResolver = ...線移動到它自己的方法,在邏輯中分離出來,並允許你可以從Resolve以上使用它。如果你這樣做了,Resolve可能就像這樣簡單:return GetTypeResolver<T>()(new TypeResolverConfiguration<T>());

+1

你仍然不能這樣做,因爲包含的類不是通用的。 'T'從哪裏來? – cadrell0

+0

@ cadrell0 Urgh ....你說得對。 –

+0

@ cadrell0 from「where T:class;」 – Marco

0

您似乎並不完全瞭解泛型是如何工作的。我會快速瀏覽一下,但請閱讀MSDN

當你有一個泛型類

public class Foo<T> 
{ 
    public T Bar {get; set;} 
} 

並且你使用這樣的事情

Foo<int> intFoo = new Foo<int>(); 
Foo<string> stringFoo = new Foo<string(); 

在編譯時,編譯器將檢測一般類型的兩種用法。它將創建每種用法的一種類型。所以你的程序集的類型看起來像這樣(不是不完全一樣,但是讓我們假裝讓人類可以理解)。

public class FooInt 
{ 
    public int Bar { get; set; } 
} 

public class FooString 
{ 
    public string Bar { get; set; } 
} 

它將與FooIntFoo<string>FooString

現在取代的Foo<int>所有用途,如果我們有一個非通用類與泛型方法

public class Foo 
{ 
    public T GetBar<T>() { ..... } 
} 

你使用它像此

Foo foo = new Foo(); 
int x = foo.GetBar<int>(); 
string s = foo.GetBar<string(); 

編譯器將生成

public class Foo 
{ 
    public int GetBarInt() { ..... } 
    public string GetBarString() { ..... } 
} 

它將與GetBarIntGetBar<string>GetBarString

更換GetBar<T>但字段是不是這樣的。如果你有一個類,看起來像這樣

public class Foo 
{ 
    public T Bar; 
} 

你不能做到這一點

Foo foo = new Foo(); 
foo.Bar<int> = 1; 
foo.Bar<string> = "test"; 

編譯器只是不明白這一點。我不是內部專家,但我的猜測是,因爲這指向了內存中的某個位置,編譯時不能在編譯時生成通用用法。

但我想說的是這一點。泛型不是一些神奇的「我不需要指定類型」功能。他們暗示編譯時說:「我將多次執行同一個任務,我希望你爲我生成代碼。」

+0

我完全知道他們是如何工作的,我不知道的是,如果有可能在委託使用的定義中設置一個約束因此是我的問題。回到我的Java時代,大約在2004年,當強大的Sun Java論壇仍在進行時,我對泛型有什麼最好的答案,我不記得確切的名字,我相信他的綽號是喬納森。但是,無論如何感謝:) – Marco