2012-05-18 63 views
5

我面臨一個要求,我的基類上創建一個靜態方法,但不喜歡我必須聲明類型參數,所以我想知道如果我去這個正確的方式。更好的方法來定義靜態方法

基本上,我指派的代表將與該類的屬性相關聯。我可以很容易地把方法上的繼承類,像這樣:

public class Foo 
{ 
    public string Property1 { get; set; } 
} 

public class InheritsFoo : Foo 
{ 
    public void AssignDel<TVal>(
     Expression<Func<InheritsFoo, TVal>> expr, 
     Action<InheritsFoo, TVal> action) 
    { 
    } 
} 

或者,在擴展類,我可以這樣做:

public static void AssignDel<T, TVal>(
    this T source, 
    Expression<T, TVal>> expression, 
    Action<T, TVal> action) 
    where T : Foo 
{ 
} 

這兩種將使我能夠使用AssignDel在一個實例化類:

var foo = new InheritsFoo(); 
foo.AssignDel(x => x.Property1, handler); 

但是我有一個要求,使AssignDel靜態的。這使得它無用的擴展方式。它仍然在InheritsFoo,但我真的想把它移到基類。如果我試試,泛型參數不能推斷,我不得不改變方法的用法:

InheritsFoo.AssignDel<InheritsFoo, string>(x => x.Property1, handler); 

有沒有辦法在這裏,這樣我都沒有想到的另一種方式?

編輯:解決該問題的意見關於是否擴展方法會/應該工作......我去了@馬克引用的網址。結果是,如果我這樣寫......

InheritsFoo foo = null; 
foo.AssignDel(x => x.Property1, handler); 

編譯(不知道它是否會運行,雖然)。不過,不要認爲這符合使用靜態方法,因爲'foo'仍然被視爲一個實例;儘管如此,仍然是一個空實例,但是是一個實例。

+3

擴展方法已經是靜態的。如何使靜態方法的要求妨礙使用擴展方法? –

+3

「我有要求使'AssignDel'靜態」。然後使其成爲靜態。 –

+1

@Kirk:儘管擴展方法被定義爲靜態方法,但它們只能用作預期類的實例方法。 –

回答

0

我能夠做到什麼,我需要的只是實現繼承鏈中另一個層次。

public class Foo 
{  
    public string Property1 { get; set; } 
} 

public class Foo<T> : Foo 
{ 
    public static void AssignDel<TVal>(Expression<Func<T, TVal>> expr, Action<T, TVal> action) 
    { } 
} 

public class InheritsFoo : Foo<InheritsFoo> 
{  } 

我可以像我需要的那樣對待InheritsFoo。

1

但我有一個要求,使AssignDel靜態。這使得 擴展方式無用。它仍然適用於InheritsFoo,但我真的想把它移到基類。如果我嘗試,仿製藥 參數不能推斷,我不得不改變 方法的用法:

這沒有意義很大。

InheritsFoo.AssignDel是一種靜態方法。

你打電話說靜態方法做InheritsFoo.AssignDel<InheritsFoo, string>(x => x.Property1, handler);它似乎符合你的要求。

我不明白你想出的第二個選項有什麼問題。它做你需要做的事情,很清楚發生了什麼事情,是因爲你通過InheritsFoostring而不是foo.AssignDel(x => x.Property1, handler);

看來你可以簡單地做下面的事情,並實現你想要的。

public class Foo 
    { 
     public string Property1 { get; set; } 
    } 

    public class InheritsFoo : Foo 
    { 
     public static void AssignDel<TVal>(
      Expression<Func<InheritsFoo, TVal>> expr, 
      Action<InheritsFoo, TVal> action) 
     { 
     } 
    } 

我必須失去了一些東西,因爲它似乎是你會使用它InheritsFoo.AssignDel(x => x.Property1, handler);這是你想要什麼。

+0

指定泛型參數確實有效,但比首選更詳細,特別是在TVal類型參數的情況下。這就是我尋求替代品的原因。 – Random

1

擴展方法已經是靜態的。

假如你要在擴展方法方式不使用它,這應該工作:

InheritsFoo.AssignDel(x => x.Property1, handler); 

以同樣的方式,編譯器將infere的擴展方法的形式類型參數,它會爲老 - 靜態的方式。

如果你需要有兩個類型paremeters的方法,你可以創建這個泛型類:

public class Foo<T> where T : Foo { 

    public void AssignDel<TVal>(Expression<Func<T, TVal>> expr, Action<T, TVal> action) 
    { 
     //... 
    } 
} 

在這種情況下,你可以這樣做:

Foo<InheritFoo>.AssignDel(x => x.PropertyFromInheritFoo, handler); 

,你可以看,你只需要聲明一個類型參數,另一個參數正在被傳遞。

希望它可以幫助

+0

如果我將方法保留在InheritsFoo中,當我想將它移動到基類Foo類時,這將起作用。 – Random

+0

哦!我遇到了你面臨的問題。看起來你是螺絲釘:( – ivowiblo

+0

所以...讓我檢查一下我是否理解:你想在Foo類中使用該方法並接受所有層次結構的屬性? – ivowiblo