2016-08-13 147 views
0

我正在用Antlr4和C#编写玩具语言。现在我正在尝试写一个类系统。但是一个大问题阻止了我所有的工作。当我尝试克隆用户创建的类的实例时,其中的所有内容都引用原始类。我的 '类' 的代码是在这里在C#中深度克隆深物体(很深)

[Serializable] 
public class Class : ICloneable 
{ 
    public string ID; 
    public ClassDef ClassContent = new ClassDef(); 

    public Helper ErrorHandler = new Helper(); 

    public Class() 
    { 
     ID = ""; 
    } 
    public Class(string id) 
    { 
     ID = id; 
    } 

    public void Create(MainGrammarParser.ClassblockContext block) 
    { 
     ClassDef def = new ClassDef(); 
     def.Visit(block); 
     ClassContent = def; 
    } 

    public object Clone() 
    { 
     Class clone = new Class(ID); 
     clone.ClassContent = ClassContent.DeepClone(); 
     return clone; 
    } 
} 

和 'ClassDef'

public class ClassDef : SuperClass, ICloneable 
{ 
    public override bool VisitClassStatFunctionDef([NotNull] MainGrammarParser.ClassStatFunctionDefContext context) 
    { 
     FunctionDefParser fd = GetFunctionDefParser(); 
     fd.Visit(context.functiondef()); 
     return true; 
    } 

    public override bool VisitClassStatElementDef([NotNull] MainGrammarParser.ClassStatElementDefContext context) 
    { 
     string id = context.classelem().ID().GetText(); 
     if (IsVarExists(id) || IsFunctionExists(id) || IsClassExists(id)) 
     { 
      ErrorHandler.DuplicateError("[ELEMENT] '" + id + "'"); 
     } 
     ExpParser exp = GetExpParser(); 
     VarObject v = new VarObject(id); 
     v.Value = exp.Visit(context.classelem().exp()); 
     Variables.Add(v); 
     return true; 
    } 
} 

和超码

public class SuperClass : MainGrammarBaseVisitor<bool>, ICloneable 
{ 
    public VarCollection Variables = new VarCollection(); 
    public FunctionCollection Functions = new FunctionCollection(); 
    public ClassCollection Classes = new ClassCollection(); 

    public Helper ErrorHandler = new Helper(); 

    public VarObject GetVar(string id) 
    { 
     if (!IsVarExists(id)) 
     { 
      ErrorHandler.NotFoundError("[DEFINITION] '" + id + "'"); 
     } 
     return Variables.Find(id); 
    } 

    public Function GetFunction(string id) 
    { 
     if (!IsFunctionExists(id)) 
     { 
      ErrorHandler.NotFoundError("[METHOD] '" + id + "'"); 
     } 
     return Functions.Find(id); 
    } 

    public Class GetClass(string id) 
    { 
     if (!IsClassExists(id)) 
     { 
      ErrorHandler.NotFoundError("[CLASS] '" + id + "'"); 
     } 
     return Classes.Find(id); 
    } 

    public bool IsVarExists(string id) 
    { 
     if (!Variables.Contains(id)) { return false; } 
     return true; 
    } 

    public bool IsFunctionExists(string id) 
    { 
     if (!Functions.Contains(id)) { return false; } 
     return true; 
    } 

    public bool IsClassExists(string id) 
    { 
     if (!Classes.Contains(id)) { return false; } 
     return true; 
    } 

    public ExpParser GetExpParser() 
    { 
     ExpParser output = new ExpParser(); 
     output.Parent = this; 
     return output; 
    } 

    public EqualityParser GetEqualityParser() 
    { 
     EqualityParser output = new EqualityParser(); 
     output.Parent = this; 
     return output; 
    } 

    public FunctionDefParser GetFunctionDefParser() 
    { 
     FunctionDefParser output = new FunctionDefParser(); 
     output.Parent = this; 
     return output; 
    } 

    public IfParser GetIfParser() 
    { 
     IfParser output = new IfParser(); 
     output.Parent = this; 
     return output; 
    } 

    public object Clone() 
    { 
     SuperClass output = new SuperClass(); 
     output.Variables = Variables.DeepClone(); 
     output.Functions = Functions.DeepClone(); 
     output.Classes = Classes.DeepClone(); 
     return output; 
    } 

    public SuperClass() 
    { } 
} 

我所著VarCollection,FunctionCollection和ClassCollection自己 他们只是代码用find和exists方法列出。 当我在语言

class abc 
{ 
    this a = "a" 
    this b = "b" 
    this c = "c" 
    void abc(){} 
} 
newabc1 = new abc() 
newabc1.a = 10 
new1a = newabc1.a 
newabc2 = new abc() 
new2a = newabc2.a 

两个“new1a”和new2a设置为10 尝试这样的代码,我想大多数的技术,包括:反射,系列化,JsonSerialization,ICloneable,MemberWiseClone ...

在序列化中,我需要将[Serializable]放到每个类中,包括Antlr4自动生成的类。所以当我更新语法时,我需要再次把它们放在一起。在Json序列化(NewtonJson)中,序列化进入一个无限循环(序列化器警告我关于自我引用循环和我禁用循环错误)。

反射,IClonable,MemberWiseClone,这些都没有正常工作。他们在内存引用相同的地址,所以我得到相同的错误。

任何帮助?

回答

0

我解决了这个问题,但不是真的:)我使用字典实例作为类(就像在JavaScript中)。在使用Antlr时,在NewtonJson中创建序列化对象是不合适的,因为巨大的源代码会使序列化非常慢(abt 2-3s)。这是我解决问题的方法。有没有人知道一个解析器生成器或一个伟大的教程来创建语言,这是我最后一个问题,然后我标记这个答案。

0

您可以使用序列化到深克隆对象,但是请记住,你必须设置:

ReferenceLoopHandling = ReferenceLoopHandling.Ignore 

你的串行,以防止无限循环的进入。这是如果您正在使用Newtonsoft,但许多序列化程序存在类似的ReferenceLoopHandling setting选项。

+0

刚试过(再次),进入了无限循环:(代码:JsonSerializerSettings设置=新JsonSerializerSettings(); settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 串序列化= JsonConvert.SerializeObject(来源设置); 回报( T)JsonConvert.DeserializeObject(序列化,设置); –

+0

@YahyaGedik您是怎么使用它的,以及您使用的是哪个版本的Newtonsoft? – meJustAndrew

+0

昨天刚刚从它的网站下载了9.0.1。大多数问题来自Antlr4自动生成的文件。因为他们是非常复杂和自我引用(?)。 –