[英]Return new instance of a class from within itself in a static method?
Okay i now you can do this as i do it, but i want to know if it can be done more seamlessly as an "auto" property kinda thing. 好的,我现在可以像我一样执行此操作,但是我想知道它是否可以作为“自动”属性更无缝地完成。
class Test : PPCNode
{
public static PPCNode ParseCode(string code)
{
string[] codeArray = SplitCode(code);
// return instance of the Instruction Node
return new Test(codeArray, 0);
}
}
So that's basically the code per say. 所以基本上这就是每个人说的代码。
Now, this code happens in Many classes, so it's identical, except the instance is for the class it's within. 现在,此代码发生在许多类中,因此它是相同的,除了实例是它所在类的实例之外。
so that's what i wonder, is it possible to make a new instance through some kind of auto thing, like. 所以这就是我想知道的,是否有可能通过某种自动方法来创建新实例,例如。
"return new ThisClass(....)" if you get my meaning. 如果您了解我的意思,请“返回新的ThisClass(....)”。
Thanks:) 谢谢:)
EDIT: 编辑:
Okay here come some examples, this will be Much code but it's easy to look through. 好了,这里有一些例子,这将是很多代码,但是很容易看透。
So here are Two Classes: 所以这是两个类:
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;
}
}
internal class AddicInstructionNode : PPCNode { private readonly string[] parameterArray; 内部类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;
}
}
And here is the Caller for those classes: 这是这些类的调用方:
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;
}
}
Sorry for the ton of code, but as you can see it's basically same thing over and over, but each class has a difference, often within the same category they only differ by 1 or 2 constant values. 对不起,有大量的代码,但是您可以一遍又一遍地看到它基本上是同一回事,但是每个类都有差异,通常在同一类别中,它们仅相差1或2个常数值。
So, as there is much copy pasting and reusing almost the same class over and over, i try to find ways to make some of it more seamless. 因此,由于存在大量的复制粘贴,并且一遍又一遍地重复使用几乎相同的类,因此我尝试找到方法使其中的一些更加无缝。
Hence why i thought returning itself auto would be nice as i wouldn't have to rename the copy paste for that every time, some small time earned;P 因此,为什么我认为自动返回自身会很好,因为我不必每次都花一些时间来重命名复制粘贴; P
No, not really. 不,不是。
Certainly not something as nice as new ThisClass()
. 当然不如
new ThisClass()
。 However, if you are returning a base class you can get away with this (not really a good idea for reasons mentioned below, but it works): 但是,如果您要返回基类, 则可以避免这种情况(由于下面提到的原因,这并不是一个好主意,但是可以):
public static BaseClass ParseCode(string data)
{
...
string declaringType = MethodBase.GetCurrentMethod().DeclaringType;
return (BaseClass)Activator.CreateInstance(declaringType);
}
Note that this is crazy expensive compared to just manually invoking your constructor, and you lose some type safety, but it would let you copy-paste. 请注意,与仅手动调用构造函数相比,这是疯狂的昂贵的操作,并且丢失了一些类型安全性,但是它将使您进行复制粘贴。
The trick is using reflection to get the declaring type (the first line) and then using Activator.CreateInstance
to invoke a constructor on that type. 诀窍是使用反射来获取声明类型(第一行),然后使用
Activator.CreateInstance
对该类型调用构造函数。 Because that returns object
you have to cast it to BaseClass
. 因为返回
object
您必须将其BaseClass
为BaseClass
。
Use this overload of CreateInstance
to pass arguments to the constructor: MSDN . 使用
CreateInstance
重载将参数传递给构造函数MSDN 。 Its the same idea though. 它是相同的想法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.