更好的方法来定义静态方法

时间:2012-05-18 16:50:10

标签: c# generics static lambda extension-methods

我面临着在我的基类上创建静态方法的要求,但不喜欢我必须声明类型参数,所以我想知道我是否正确地采用了这种方法。

基本上,我正在分配我将与课堂上的属性相关联的代表。我可以轻松地将该方法放在继承的类上,如下所示:

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);

这里有没有办法,另一种方法是我没想到的?

编辑:在关于扩展方法是否/应该工作的评论中解决问题...我去了@Mark M.引用的网址。如果我这样写的那么...... < / p>

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

编译(不知道它是否会运行)。不过,不要认为这有资格使用静态方法,因为'foo'仍然被认为是一个实例;一个null实例,但仍然是一个实例。

3 个答案:

答案 0 :(得分: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);,这正是你想要的。

答案 1 :(得分:1)

扩展方法已经是静态的。

假设您不必以扩展方法方式使用它,这应该有效:

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

编译器以相同的方式推断扩展方法表单的类型参数,它将采用老式的静态方式。

如果您需要具有两种类型参数的方法,您可以为此创建一个通用类:

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); 

正如您所看到的,您只需要声明一个类型参数,另一个是被推测的。

希望有所帮助

答案 2 :(得分: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。