c#将此返回给泛型返回类型方法

时间:2014-11-04 04:56:43

标签: c#

我班级中的许多方法都会return this;,这样我就可以在一行内调用多个函数。当我尝试创建基类时会出现a.method1().method2().method3();问题。如果我创建一个方法在基类中返回类型T,那么我不能再return this;,因为基类类型不是T。我不能只将返回类型作为基类,因为继承的类上有许多不在基类中的方法。我该如何解决这个问题?

示例代码:

public class baseClass<T>
{
    public T method1()
    {
        //Do stuffs
        return this;//doesnt work
    }
}

public class inheritedClass:baseClass<inheritedClass>
{
    public inheritedClass method2()
    {
        //Do stuffs
        return this;
    }
}

3 个答案:

答案 0 :(得分:1)

您的基类的返回类型应该是基类本身,而不仅仅是T。

public class baseClass<T>
{
    public baseClass<T> method1()
    {
        //Do stuffs
        return this;
    }
}

答案 1 :(得分:1)

在您的基类示例中,&#34;此&#34;不是一种&#34; T&#34;但它是一种&#34; baseClass {T}&#34;。这就是为什么它不起作用的原因。我不确定你在这里要做什么,但这可能会编译...

public class baseClass<T>
{
  public baseClass<T> method1()
  {
    return this;
  }
}

public class inheritedClass : baseClass<inheritedClass>
{
  public baseClass<inheritedClass> method2()
  {
    return this.method1();
  }
}

编辑:我现在明白你的问题。这可能是比使用继承更好的整体方法。如果需要,您可以将接口转换为通用接口...

public interface FluentStuff
{
  FluentStuff method1();
  FluentStuff method2();
}

public class MyClass : FluentStuff
{
  public FluentStuff method1()
  {
    return this;
  }

  public FluentStuff method2()
  {
    return this;
  }
}

但是如果你坚持使用继承......

public interface FluentStuff
{
  FluentStuff method1();
  FluentStuff method2();
}

public abstract class BaseClass : FluentStuff
{
  public virtual FluentStuff method1()
  {
    return this;
  }

  public abstract FluentStuff method2();
}

public class MyClass : BaseClass, FluentStuff
{
  public override FluentStuff method2()
  {
    return this;
  }
}

我强烈鼓励作文而不是继承。

泛型的例子......

public interface FluentStuff<T>
{
  FluentStuff<T> method1();
  FluentStuff<T> method2();
}

public abstract class BaseClass<T> : FluentStuff<T>
{
  public virtual FluentStuff<T> method1()
  {
    return this;
  }

  public abstract FluentStuff<T> method2();
}

public class MyClass : BaseClass<MyClass>, FluentStuff<MyClass>
{
  public override FluentStuff<MyClass> method2()
  {
    return this;
  }
}

你发布的另一个问题/疑虑的最后一个例子......

public class SharedFunctionality
{
  public void DoStuff1()
  {
    // common implementation for do stuff 1
  }

  public void DoStuff2()
  {
    // common implementation for do stuff 2
  }
}

public class MyClass1
{
  private readonly SharedFunctionality sharedFunctionality;

  public MyClass1()
  {
    this.sharedFunctionality = new SharedFunctionality();
  }

  public MyClass1 Method1()
  {
    this.sharedFunctionality.DoStuff1();
    return this;
  }

  public MyClass1 Method2()
  {
    this.sharedFunctionality.DoStuff2();
    return this;
  }
}

public class MyClass2
{
  private readonly SharedFunctionality sharedFunctionality;

  public MyClass2()
  {
    this.sharedFunctionality = new SharedFunctionality();
  }

  public MyClass2 Method1()
  {
    this.sharedFunctionality.DoStuff1();
    return this;
  }

  public MyClass2 Method2()
  {
    this.sharedFunctionality.DoStuff2();
    return this;
  }

  public MyClass2 Method3()
  {
    // do something only this class does
    return this;
  }
}

class Program
{
  static void Main(string[] args)
  {
    MyClass1 c1 = new MyClass1();
    c1.Method1().Method2();

    MyClass2 c2 = new MyClass2();
    c2.Method1().Method2().Method3();
  }
}

答案 2 :(得分:1)

可能是这个

public abstract class BaseClass<T> where T : BaseClass<T>
{
    public T Method1()
    {
        //Do stuffs

        // We are sure any instance of this class is T : BaseClass<T>. 
        // Only exception might be direct instance of BaseClass<T> and that's why we made BaseClass abstract.
        return (T)this;
    }
}  

public class InheritedClass : BaseClass<InheritedClass>
{
    public InheritedClass Method2()
    {
        //Do stuffs
        return this;
    }
}

改变了两件事。首先,我们仍在施法,但在基类中这样做。其次,我们保证这个强制转换适用于约束和抽象。