如何在C#中链接方法时进行强制转换

本文关键字:转换 方法 链接 | 更新日期: 2023-09-27 18:09:38

我正在尝试编码一些东西,我总是返回对象本身,这样我就可以继续链接了。像这个

object.SetThis().SetThat().SetThisThirdThing().setThisFourthThing();

我在所有的方法中都返回了这个,这样我就可以继续这样做了。但是我的一个方法是我在基类中创建的,当然它会返回基类。

因此,它返回的不是public MyClass SetThat(),而是public SuperClass SetThat()。因为它返回SuperClass而不是MyClass,所以我不能调用SetThisThirdThing(),因为基类不知道它

那么我该如何铸造才能保住链子呢?语法是什么?我试过

object.SetThis().(MyClass)SetThat().SetThisThirdThing().setThisFourthThing();

或者有没有一种方法可以让superClass方法在从子类调用时返回子类,而不必在所有子类中重写它?

这是所有子类的共同点之一,所以如果我能够以某种方式绕过它,而不必在所有子类中覆盖它,那就太好了。

如何在C#中链接方法时进行强制转换

有没有一种方法可以让superClass方法在从子类调用时返回子类,而不必在所有子类中重写它?

你能让超类成为泛型吗?

public class SuperClass<T> where T: SuperClass<T>
{
    public T SetThis()
    {
        ....
        return (T)this;
    }
}
public class SubClass : SuperClass<SubClass>
{
}

注意,它不是100%保证,因为你也可以这样做:

public class EvilSubClass : SuperClass<SubClass>
{
}

符合一般约束,但现在SetThis()的返回类型是SubClass,而不是EvilSubClass

var obj = ((MyType)myObject.SetThis()).SetThat();

p.S你应该避免那样做,因为读起来会很困惑。

若要强制转换(子(表达式,需要将类名放在前面(并使用括号(。

((MyClass)obj.SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();

(注意,object是一个保留字,因此不能将其用作变量名(

另一种选择是使用as关键字:

(obj.SetThis().setThat() as MyClass).SetThisThirdThing().setThisFourthThing();

注意,如果setThat()不返回MyClass,则这将表现不同;第一个版本将抛出InvalidCastException,第二个版本抛出NullReferenceException,因为如果不能进行强制转换,as将返回null

这样尝试:

((MyClass)object.SetThis().SetThat()).SetThisThirdThing()

只需使用括号:

(MyClass)(object.SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();

我不知道为什么object在那里,但你可以安全地把它取下来。

(MyClass)(SetThis().SetThat()).SetThisThirdThing().setThisFourthThing();

在不修改类的情况下,您还可以编写类似的扩展方法As

public static T As<T>(this MyBaseClass obj) where T : MyBaseClass
{
   return (T)obj;
}

--

用途与此类似

new MyChildClass().SetBase().As<MyChildClass>().SetThis();

为什么不这样做?一个简单的Cast方法可以帮助您将其转换回正确的类型。。。

class Program
{
    static void Main(string[] args)
    {
        var obj = new MyClass();
        //obj.SetThis().SetThat().SetThisThirdThing().setThisFourthThing(); // Compile error
        obj.SetThis().SetThat().Cast<MyClass>().SetThisThirdThing().setThisFourthThing();
    }
}
class SuperClass
{
    public SuperClass SetThat()
    {
        return this;
    }
    public T Cast<T>() where T : SuperClass
    {
        return (T)this;
    }
}
class MyClass : SuperClass
{
    public MyClass SetThis()
    {
        return this;
    }
    public MyClass SetThisThirdThing()
    {
        return this;
    }
    public MyClass setThisFourthThing()
    {
        return this;
    }
}