繁体   English   中英

从自己内部以静态方法返回类的新实例?

[英]Return new instance of a class from within itself in a static method?

好的,我现在可以像我一样执行此操作,但是我想知道它是否可以作为“自动”属性更无缝地完成。

class Test : PPCNode
    {

        public static PPCNode ParseCode(string code)
        {
            string[] codeArray = SplitCode(code);

            // return instance of the Instruction Node
            return new Test(codeArray, 0);
        }
    }

所以基本上这就是每个人说的代码。

现在,此代码发生在许多类中,因此它是相同的,除了实例是它所在类的实例之外。

所以这就是我想知道的,是否有可能通过某种自动方法来创建新实例,例如。

如果您了解我的意思,请“返回新的ThisClass(....)”。

谢谢:)

编辑:

好了,这里有一些例子,这将是很多代码,但是很容易看透。

所以这是两个类:

internal class AddicDotInstructionNode : PPCNode
    {
        private readonly string[] parameterArray;

        private AddicDotInstructionNode(string[] codeArray)
        {
            parameterArray = codeArray;

            // Throw exception if the number of parameters is invalid to instruction
            if (codeArray.Length != 3)
                throw new Exception($"\"{GetType().Name}\" instruction is invalid");
        }

        public static PPCNode ParseCode(string code)
        {

            // Split the code string into an array so each element is a parameter
            string[] codeArray = code.Split(',');

            // return instance of the Instruction Node
            return new AddicDotInstructionNode(codeArray);
        }

        // +-------------------------------------+------------+----------------+-------------------------------------------------+
        // | 0                                 5 | 6 7 8 9 10 | 11 12 13 14 15 | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
        // +-------------------------------------+------------+----------------+-------------------------------------------------+
        // |                  13                 |      D     |        A       |                       SIMM                      |
        // +-------------------------------------+------------+----------------+-------------------------------------------------+
        public override int Compile()
        {
            int opcode = 13;

            int regD = Utility.PPCUtility.GetParameterDigit(parameterArray[0]);
            int regA = Utility.PPCUtility.GetParameterDigit(parameterArray[1]);
            int simm = Utility.PPCUtility.Get16bitHexorDecimalAsUint(parameterArray[2]);

            // opcode at 0-5 (26-31)
            // Register D at 6-10 (21-25)
            // Register A at 11-15 (16-20)
            // SIMM at 16-31 (0-15)
            return opcode << 26 | regD << 21 | regA << 16 | simm;
        }
}

内部类AddicInstructionNode:PPCNode {私有只读字符串[] parameterArray;

    private AddicInstructionNode(string[] codeArray)
    {
        parameterArray = codeArray;

        // Throw exception if the number of parameters is invalid to instruction
        if (codeArray.Length != 3)
            throw new Exception($"\"{GetType().Name}\" instruction is invalid");
    }

    public static PPCNode ParseCode(string code)
    {

        // Split the code string into an array so each element is a parameter
        string[] codeArray = code.Split(',');

        // return instance of the Instruction Node
        return new AddicInstructionNode(codeArray);
    }

    // +-------------------------------------+------------+----------------+-------------------------------------------------+
    // | 0                                 5 | 6 7 8 9 10 | 11 12 13 14 15 | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
    // +-------------------------------------+------------+----------------+-------------------------------------------------+
    // |                  12                 |      D     |        A       |                       SIMM                      |
    // +-------------------------------------+------------+----------------+-------------------------------------------------+
    public override int Compile()
    {
        int opcode = 12;

        int regD = Utility.PPCUtility.GetParameterDigit(parameterArray[0]);
        int regA = Utility.PPCUtility.GetParameterDigit(parameterArray[1]);
        int simm = Utility.PPCUtility.Get16bitHexorDecimalAsUint(parameterArray[2]);

        // opcode at 0-5 (26-31)
        // Register D at 6-10 (21-25)
        // Register A at 11-15 (16-20)
        // SIMM at 16-31 (0-15)
        return opcode << 26 | regD << 21 | regA << 16 | simm;
    }
}

这是这些类的调用方:

internal static class IntegerArithmeticInstructionNode
    {
        // PowerPC: Table A-2 Integer Arithmetic Instructions (Complete)
        public static Func<string, PPCNode> ParseInstruction(string code)
        {
            switch (code)
            {
                // Addx
                case "add": return AddInstructionNode.ParseCode;
                case "add.": return AddInstructionNode.ParseCodeRc;
                case "addo": return AddInstructionNode.ParseCodeOe;
                case "addo.": return AddInstructionNode.ParseCodeOeRc;

                // Addcx
                case "addc": return AddcInstructionNode.ParseCode;
                case "addc.": return AddcInstructionNode.ParseCodeRc;
                case "addco": return AddcInstructionNode.ParseCodeOe;
                case "addco.": return AddcInstructionNode.ParseCodeOeRc;

                // Addex
                case "adde": return AddeInstructionNode.ParseCode;
                case "adde.": return AddeInstructionNode.ParseCodeRc;
                case "addeo": return AddeInstructionNode.ParseCodeOe;
                case "addeo.": return AddeInstructionNode.ParseCodeOeRc;

                // Addi
                case "addi": return AddiInstructionNode.ParseCode;

                // Addic
                case "addic": return AddicInstructionNode.ParseCode;

                // Addic.
                case "addic.": return AddicDotInstructionNode.ParseCode;

                // Addis
                case "addis": return AddisInstructionNode.ParseCode;

                // Addmex
                case "addme": return AddmeInstructionNode.ParseCode;
                case "addme.": return AddmeInstructionNode.ParseCodeRc;
                case "addmeo": return AddmeInstructionNode.ParseCodeOe;
                case "addmeo.": return AddmeInstructionNode.ParseCodeOeRc;

                // Addzex
                case "addze": return AddzeInstructionNode.ParseCode;
                case "addze.": return AddzeInstructionNode.ParseCodeRc;
                case "addzeo": return AddzeInstructionNode.ParseCodeOe;
                case "addzeo.": return AddzeInstructionNode.ParseCodeOeRc;

                // Divwx
                case "divw": return DivwInstructionNode.ParseCode;
                case "divw.": return DivwInstructionNode.ParseCodeRc;
                case "divwo": return DivwInstructionNode.ParseCodeOe;
                case "divwo.": return DivwInstructionNode.ParseCodeOeRc;

                // Divwux
                case "divwu": return DivwuInstructionNode.ParseCode;
                case "divwu.": return DivwuInstructionNode.ParseCodeRc;
                case "divwuo": return DivwuInstructionNode.ParseCodeOe;
                case "divwuo.": return DivwuInstructionNode.ParseCodeOeRc;

                // Mulhwx
                case "mulhw": return MulhwInstructionNode.ParseCode;
                case "mulhw.": return MulhwInstructionNode.ParseCodeRc;

                // Mulhwux
                case "mulhwu": return MulhwuInstructionNode.ParseCode;
                case "mulhwu.": return MulhwuInstructionNode.ParseCodeRc;

                // Mulli
                case "mulli": return MulliInstructionNode.ParseCode;

                // Mullwx
                case "mullw": return MullwInstructionNode.ParseCode;
                case "mullw.": return MullwInstructionNode.ParseCodeRc;
                case "mullwo": return MullwInstructionNode.ParseCodeOe;
                case "mullwo.": return MullwInstructionNode.ParseCodeOeRc;

                // Negx
                case "neg": return NegInstructionNode.ParseCode;
                case "neg.": return NegInstructionNode.ParseCodeRc;
                case "nego": return NegInstructionNode.ParseCodeOe;
                case "nego.": return NegInstructionNode.ParseCodeOeRc;

                // Subfx
                case "subf": return SubfInstructionNode.ParseCode;
                case "subf.": return SubfInstructionNode.ParseCodeRc;
                case "subfo": return SubfInstructionNode.ParseCodeOe;
                case "subfo.": return SubfInstructionNode.ParseCodeOeRc;

                // Subx (equivalent to Subf with swaped rA and rB)
                case "sub": return SubInstructionNode.ParseCode;
                case "sub.": return SubInstructionNode.ParseCodeRc;
                case "subo": return SubInstructionNode.ParseCodeOe;
                case "subo.": return SubInstructionNode.ParseCodeOeRc;

                // Subfcx
                case "subfc": return SubfcInstructionNode.ParseCode;
                case "subfc.": return SubfcInstructionNode.ParseCodeRc;
                case "subfco": return SubfcInstructionNode.ParseCodeOe;
                case "subfco.": return SubfcInstructionNode.ParseCodeOeRc;

                // Subcx (equivalent to Subfc with swaped rA and rB)
                case "subc": return SubcInstrucionNode.ParseCode;
                case "subc.": return SubcInstrucionNode.ParseCodeRc;
                case "subco": return SubcInstrucionNode.ParseCodeOe;
                case "subco.": return SubcInstrucionNode.ParseCodeOeRc;

                // Subfe
                case "subfe": return SubfeInstructionNode.ParseCode;
                case "subfe.": return SubfeInstructionNode.ParseCodeRc;
                case "subfeo": return SubfeInstructionNode.ParseCodeOe;
                case "subfeo.": return SubfeInstructionNode.ParseCodeOeRc;

                // Subfic
                case "subfic": return SubficInstructionNode.ParseCode;

                // Subme
                case "subfme": return SubfmeInstructionNode.ParseCode;
                case "subfme.": return SubfmeInstructionNode.ParseCodeRc;
                case "subfmeo": return SubfmeInstructionNode.ParseCodeOe;
                case "subfmeo.": return SubfmeInstructionNode.ParseCodeOeRc;

                // Subze
                case "subfze": return SubfzeInstructionNode.ParseCode;
                case "subfze.": return SubfzeInstructionNode.ParseCodeRc;
                case "subfzeo": return SubfzeInstructionNode.ParseCodeOe;
                case "subfzeo.": return SubfzeInstructionNode.ParseCodeOeRc;

            }

            return null;
        }
    }

对不起,有大量的代码,但是您可以一遍又一遍地看到它基本上是同一回事,但是每个类都有差异,通常在同一类别中,它们仅相差1或2个常数值。

因此,由于存在大量的复制粘贴,并且一遍又一遍地重复使用几乎相同的类,因此我尝试找到方法使其中的一些更加无缝。

因此,为什么我认为自动返回自身会很好,因为我不必每次都花一些时间来重命名复制粘贴; P

不,不是。

当然不如new ThisClass() 但是,如果您要返回基类, 可以避免这种情况(由于下面提到的原因,这并不是一个好主意,但是可以):

public static BaseClass ParseCode(string data)
{
    ...
    string declaringType = MethodBase.GetCurrentMethod().DeclaringType; 
    return (BaseClass)Activator.CreateInstance(declaringType);
}

请注意,与仅手动调用构造函数相比,这是疯狂的昂贵的操作,并且丢失了一些类型安全性,但是它将使您进行复制粘贴。

诀窍是使用反射来获取声明类型(第一行),然后使用Activator.CreateInstance对该类型调用构造函数。 因为返回object您必须将其BaseClassBaseClass

使用CreateInstance重载将参数传递给构造函数MSDN 它是相同的想法。

暂无
暂无

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

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