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

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

编辑:为了解决关于扩展方法是否/应该工作的评论中的问题......我去了@Mark M引用的网址。事实证明,如果我这样写......

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

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

4

3 回答 3

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

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

希望能帮助到你

于 2012-05-18T17:29:19.013 回答
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);正是你想要的。

于 2012-05-18T17:24:57.317 回答
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。

于 2012-06-06T23:27:13.573 回答