C# 定义静态方法的更好方法

C# 定义静态方法的更好方法,c#,generics,static,lambda,extension-methods,C#,Generics,Static,Lambda,Extension Methods,我面临着在基类上创建静态方法的要求,但我不喜欢这样,我必须声明类型参数,所以我想知道我这样做是否正确 基本上,我分配的委托将与类上的属性相关联。我可以很容易地将该方法放在继承的类上,如下所示: public class Foo { public string Property1 { get; set; } } public class InheritsFoo : Foo { public void AssignDel<TVal>( Expressi

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

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

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) 
    {
    }
}

但是我需要使
AssignDel
static。这使得扩展方法没有用。它仍然在
InheritsFoo
中工作,但我真的想把它移到基类。如果我尝试,则无法推断泛型参数,并且我必须更改该方法的用法:

InheritsFoo.AssignDel<InheritsFoo, string>(x => x.Property1, handler);
编译(但不知道它是否会运行)。不过,不要认为这符合使用静态方法的条件,因为“foo”仍然被视为一个实例;一个空实例,但仍然是一个实例

但我有一个要求,使它成为静态的。这使得 做这件事的方法是无用的。它在InheritsFoo中仍然有效,但是 我真的想把它移到基类。如果我尝试,泛型 无法推断参数,我必须更改 方法:

这没有多大意义

InheritsFoo.AssignDel
是一种静态方法

通过执行
InheritsFoo.AssignDel(x=>x.Property1,handler)调用所述静态方法它似乎符合您的要求

我不明白你提出的第二个选择有什么问题。它做了您需要做的事情,很清楚发生了什么,这真的是因为您传递了
InheritsFoo
string
,而不是
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) 
        {
        }
    }
公共类Foo
{
公共字符串属性1{get;set;}
}
公共类继承Foo:Foo
{
公共静态无效分配(
表达式表达式,
行动(行动)
{
}
}

我肯定遗漏了什么,因为您似乎会使用它
InheritsFoo.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);
编译器将以同样的方式推断扩展方法形式的类型参数,也将以老式的静态方式推断类型参数

如果需要具有两个类型参数的方法,可以为此创建泛型类:

public class Foo<T> where T : Foo {

    public void AssignDel<TVal>( Expression<Func<T, TVal>> expr, Action<T, TVal> action) 
    {
         //...
    }
}
公共类Foo,其中T:Foo{
public void AssignDel(表达式表达式、动作)
{
//...
}
}
在这种情况下,您可以执行以下操作:

Foo<InheritFoo>.AssignDel(x => x.PropertyFromInheritFoo, handler); 
Foo.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>
{     } 
公共类Foo
{    
公共字符串属性1{get;set;}
} 
公开课Foo:Foo
{
公共静态void AssignDel(表达式表达式、动作)
{   }
}
公共类继承Foo:Foo
{     } 

我可以按需要处理InheritsFoo。

扩展方法已经是静态的。使方法成为静态的需求如何妨碍使用扩展方法?“我需要使
AssignDel
static”。Kirk:虽然扩展方法被定义为静态方法,但它们只能用作目标类的实例方法。我不清楚您想要什么。但是您可以将基类设置为泛型,
公共类Foo
。然后,您可以根据类型
T
在基类上编写一个静态方法。然后,当您编写派生类时,您可以将
InheritsFoo
设为非泛型,并从“构造类型”派生,如下所示:
public class InheritsFoo:Foo
@MarkM:我认为令人困惑的一句话是“但是它们被调用时就好像它们是扩展类型上的实例方法一样。”为了使您所说的话成为真,它应该这样说“但它们只被称为。。。" ;)指定泛型参数确实有效,但比首选参数更详细,尤其是在TVal类型参数的情况下。这就是为什么我要寻找替代方案。如果我将方法保留在InheritsFoo中,当我想将其移动到基类Foo时,这将起作用。哦!我知道你面临的问题。看来你疯了:(那么…让我检查一下我是否理解了:您想在Foo类中拥有该方法并接受所有层次结构的属性?@ivowiblo…有点。该方法中的实际代码不需要计算属性,我将它用作将委托分配给内部字典的键。计算属性表达式的反射uld工作良好,即使在基类中也是如此。
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>
{     }