定义静态方法的更好方法



>我面临着在我的基类上创建一个静态方法的要求,但不喜欢我必须声明类型参数,所以我想知道我是否以正确的方式做到这一点。

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

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 引用的网址。 事实证明,如果我这样写...

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

编译(不过不知道它是否会运行(。 不过,不要认为这符合使用静态方法的条件,因为"foo"仍然被视为一个实例; 一个空实例,但仍然是一个实例。

但是我要求使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);这正是您想要的。

扩展方法已经是静态的。

假设您不必以扩展方法的方式使用它,这应该可以工作:

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

如您所见,您只需要声明一个类型参数,另一个正在推断。

希望对你有帮助

我设法通过在继承链中实现另一个级别来做我需要的事情。

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。

最新更新