简体   繁体   English

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

[英]How to cast when chaining methods in C#

I'm trying to code something, and I always return the object itself so I can keep chaining. 我正在尝试编写一些东西,而且我总是返回对象本身,所以我可以继续链接。 Like this 像这样

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

I return this in all my methods so I can keep doing this. 我在所有方法中都返回这个,所以我可以继续这样做。 But one of my methods is something I made in my base class, which of course then returns the base class. 但是我的一个方法是我在基类中创建的,当然然后返回基类。

So instead of public MyClass SetThat() it returns public SuperClass SetThat() . 因此,它不是public MyClass SetThat()而是返回public SuperClass SetThat() And because it returns SuperClass and not MyClass I can't call SetThisThirdThing() because the base class doesn't know about it. 因为它返回SuperClass而不是MyClass所以我无法调用SetThisThirdThing()因为基类不知道它。

So how do I cast it so I can keep the chain? 那么我如何施展它以便我能保持链条? What is the syntax? 语法是什么? I tried 我试过了

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

Or is there a way to make a superClass method return the subclass when called from the subclass without having to override it in all the subclasses? 或者有没有办法让superClass方法在从子类调用时返回子类,而不必在所有子类中重写它?

This is one of the things that all the subclasses have in common, so it would be really nice if I would be able to circumvent this somehow without having to override it in all my subclasses. 这是所有子类共有的东西之一,所以如果我能够以某种方式绕过它而不必在所有子类中覆盖它,那将是非常好的。

is there a way to make a superClass method return the subclass when called from the subclass without having to override it in all the subclasses? 有没有办法让superClass方法在从子类调用时返回子类,而不必在所有子类中重写它?

Can you make the superclass generic? 你能让超类通用吗?

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

public class SubClass : SuperClass<SubClass>
{
}

Note that it's not 100% guaranteed since you could also do this: 请注意,它不是100%保证,因为您也可以这样做:

public class EvilSubClass : SuperClass<SubClass>
{
}

which fits the generic contraints, but now the return type of SetThis() is SubClass and not EvilSubClass 这符合通用SetThis() ,但现在SetThis()的返回类型是SubClass而不是EvilSubClass

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

PS你应该避免这样做,因为阅读可能会让人感到困惑。

试试这样:

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

To cast a (sub)expression, you need to put the class name in front (and use parentheses). 要转换(子)表达式,您需要将类名放在前面(并使用括号)。

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

(note that object is a reserved word, so you can't use it as a variable name) (请注意, object是保留字,因此您不能将其用作变量名)

An alternative is to use the as keyword: 另一种方法是使用as关键字:

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

Note that this will behave differently if setThat() doesn't return a MyClass ; 请注意,如果setThat()没有返回MyClass ,这将表现不同; the first version will throw an InvalidCastException , the second version a NullReferenceException because as returns null if the cast is not possible. 第一个版本将抛出InvalidCastException ,第二个版本NullReferenceException ,因为as回报null如果转换是不可能的。

Just use parenthesis: 只需使用括号:

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

I don't know why the object is there, but you can safely remove it. 我不知道为什么object存在,但你可以安全地删除它。

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

Without modifying your classes, you can also write an extension method As like this 无需修改类,你也可以写一个扩展方法As这样的

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

-- -

Usage would be similar to this 用法与此类似

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

Why not do it like this? 为什么不这样做呢? A simple Cast method to help you cast it back to the correct type... 一个简单的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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM