الملكية لاغيا، حتى بعد أن وضع في التعليمات البرمجية

StackOverflow https://stackoverflow.com/questions/812793

  •  03-07-2019
  •  | 
  •  

سؤال

ولقد تم في محاولة لحل هذه للأعمار (3 أيام) الآن وأنا فقط لا يمكن معرفة ذلك. سأحاول شرح المشكلة شامل لأنه هو قليلا أكثر تعقيدا.

واحالة مدرستي هو لخلق لعبة نصية بسيطة باستخدام OOP في C # البصرية ستوديو 2008 (يجب أن تكون مبنية على مكتبة المعلم قدمت للولايات المتحدة). فقط يجب أن تستخدم وحدة التحكم. لدي خبرة لائقة مع OOP PHP من وC ++ ولكن ما زلت لا يمكن معرفة ذلك.

و80٪ من اللعبة نص تعمل بالفعل ولذا فإنني لن يحمل لكم مع الطبقات والأشياء التي تعمل بالفعل ولا علاقة لهذه المشكلة. حسنا دعونا نبدأ:

ويتم تمثيل كل أمر في لعبة (ماذا يمكنك كتابة إلى وحدة التحكم واضغط) من قبل فئة واحدة على حد سواء توسيع فئة مجردة واجهة من مكتبة أنا من المفترض أن يبنى اللعبة على. رفع الصوت عاليا هو استخدام الطبقة التي تمثل القيادة لاستخدام وحدات (على سبيل المثال قمت بكتابة "استخدام السيف" إلى وحدة التحكم واللعبة سوف تبحث عن عنصر يسمى السيف، وندعو طريقة استخدامه):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Game.Commands
{
    class Use : TextGame.Commands.ACommand, TextGame.Commands.ICommand
    {
        private string name;
        public new string Name
        {
            set { this.name = value; }
            get { return this.name; }
        }

        private string description;
        public new string Description
        {
            set { this.description = value; }
            get { return this.description; }
        }

        private string parameters;
        public new string Params
        {
            set { this.parameters = value; }
            get { return this.parameters; }
        }

        public Use(string name, string description) : base(name, description)
        {
            this.name = name;
            this.description = description;
        }

        private TextGame.Core.GameState gameState;
        public TextGame.Core.GameState Execute(TextGame.Core.IGame game)
        {
            // This is just a test because it appears the problem is
            // with the parameters property. There should be a command
            // you have typed in the console but its always null
            // Note that I have not yet coded the body of this method.
            // I will do that once I solve the problem.
            if (this.parameters == null)
            {
                Console.WriteLine("is null");
            }
            else
            {
                Console.WriteLine(this.parameters);
            }
            return this.gameState;
        }
    }
}

وهناك نوعان من الفئات الأخرى التي يتم استخدامها. الطبقة محلل والطبقة لعبة. هناك لفترة أطول قليلا لذلك أنا سوف الرد فقط قصاصات من الاشياء ذات الصلة منها. الطبقة محلل:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections; // ArrayList, Dictionary, Hashtable
using System.Text.RegularExpressions; // regex engine
using Game.Commands;

namespace Game
{
    class Parser
    {
        private ArrayList commands = new ArrayList();

        // All commands that are available in the game so far are
        // initialized here in the constructor (and added to the arraylist)...
        // skip to the other method this is not important
        public Parser()
        {
            this.commands.Add(new North("^north", "Go north"));
            this.commands.Add(new South("^south", "Go south"));
            this.commands.Add(new East("^east", "Go east"));
            this.commands.Add(new West("^west", "Go west"));
            this.commands.Add(new Use("^use\\s\\w+", "Try to use the selected item"));
            this.commands.Add(new Quit("^quit", "Quit the game"));
        }

        // This method takes as an argument a string representing
        // a command you type in the console. It then searches the arraylist
        // via the regex. If the command exists, it returns an the command object
        // from the arraylist
        // This works fine and returns right objects (tested)
        public TextGame.Commands.ACommand GetCommand(string command)
        {
            TextGame.Commands.ACommand ret = null;
            foreach (TextGame.Commands.ACommand c in this.commands)
            {
                Regex exp = new Regex(@c.Name, RegexOptions.IgnoreCase);
                MatchCollection MatchList = exp.Matches(command);
                if (MatchList.Count > 0)
                {
                    ret = c;
                }
            }
            return ret;
        }
    }
}

والآن قصاصة من الطبقة لعبة حيث أنا باستخدام كلتا الفئتين أعلاه:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TextGame.Core;
using System.Collections;
using Game.Items;
using Game.Commands;

namespace Game
{
    class Game : TextGame.Core.IGame
    {

        public void Play()
        {   
            // Here I read commands from the console in a loop and
            // call the ProcessCommand() method. No problem here.
            while (true)
            {
                string command = Console.ReadLine();
                this.ProcessCommand(command);
            }
        }

        // This is the IMPORTANT method so take a closer look
        private TextGame.Core.GameState gameState;
        public TextGame.Core.GameState ProcessCommand(string command)
        {
            Parser parser = new Parser();
            TextGame.Commands.ACommand c = parser.GetCommand(command);
            if (c != null)
            {
                // HERE I ADD THE COMMAND FROM THE CONSOLE TO THE C OBJECT
                // I ADD IT VIA THE SETTER TO THE PARAMETERS PROPERTY
                // OF THE COMMAND
                c.Params = command;
                // AND I CALL THE COMMAND'S EXECUTE() METHOD - SEE THE FIRST CLASS -
                // USE - WHERE I TEST FOR THE PARAMS PROPERTY BUT IT IS STILL NULL
                this.gameState = ((TextGame.Commands.ICommand)c).Execute(this);
            }
        }
    }
}
تعليقات

ولقد أضاف إلى قصاصات لوصف أين المشكلة. أرجو أن أكون قد أوضحت ذلك بشكل جيد.

وأي شخص لديه أي أفكار؟ لقد تم العمل على هذه المشاريع لمدة 3 أسابيع حتى الآن، ومعظم الاشياء بسلاسة عندما جئت قبل 3 أيام عبر هذه المشكلة ومنذ ذلك الحين وأنا أحاول الحصول على رأسي تغلب على هذه المشكلة.

هل كانت مفيدة؟

المحلول

والمشكلة هي مع الكلمة "الجديدة". هنا حيث كنت استخدامه في 'استخدام' الفئة:

    private string parameters;
    public new string Params
    {
        set { this.parameters = value; }
        get { return this.parameters; }
    }

وأنت تقوم بإنشاء خاصية مختلفة أن يحدث لمجرد أن لديهم نفس اسم كخاصية على نوع كنت يرث من. الكلمة "الجديدة" يقول المترجم يعني لك أن تفعل ذلك.

والأساس، وهذا يعني أنه إذا كنت تفعل ما يلي:

var x = new Use();
x.Params = "abcd";
((ACommand)x).Params = "wxyz";
Console.Writeline("direct: " + x.Params);
Console.Writeline("ACommand: " + ((ACommand)x).Params);

وستحصل على هذا الإخراج:

<اقتباس فقرة>   

ومباشرة: ABCD

     

وACommand: ط ظ ع غ

وربما كنت ترغب في إزالة تعريف "بارامس" كليا من استخدام ومجرد وراثة واحد من ACommand. ربما من الاسم والوصف أيضا، ولكن يجب أن تكون قادرة على معرفة من هنا إذا كنت تريد ذلك أم لا.

نصائح أخرى

ودون رؤية رمز للطبقة ACommand ... حاول إزالة المشغل "الجديد" في الإعلان بارامس الطبقة الاستخدام عند وضع الخاص بك c.Params الملكية = الأمر. هو في الواقع إعداد الخاصية من الفئة الأساسية، في تنفيذ طريقة ديك التحقق this.parameters بدلا من base.Params.

<اقتباس فقرة>   

و// هذا هو مجرد اختبار لأنه يبدو أن المشكلة هي
  // مع الخاصية المعلمات. يجب أن تكون هناك قيادة و
  // كنت قد كتبته في وحدة تحكم ولكن دائما لاغيا
لها   // ملاحظة أنني لم مشفرة بعد الجسم من هذا الأسلوب.
  // أنا سوف نفعل ذلك مرة واحدة في حل المشكلة.

ويحدث هذا بسبب كنت معلنا جديدا على الممتلكات الخاصة بك. يجب أن تكون هذه التجاوز، أو غير المدرجة على الإطلاق إذا كنت لا تحتاج إلى تغيير منطق ACommand.

وعند الرجوع باعتبارها ACommand:

TextGame.Commands.ACommand c = parser.GetCommand(command);            
c.Params = command;

وسوف تستخدم إما بارامس ACommand، وأو تجاوز الخاص بك (إذا كنت قد حددت واحد).

والجديد الخاص بك بارامس الظل ACommand في بارامس، ويمكن الوصول إليها إلا إذا رجوع اليها هي UseCommand.

والمشكلة هي هنا:

private string parameters;
public new string Params
{
    set { this.parameters = value; }
    get { return this.parameters; }
}

في التعليمات البرمجية:

c.Params = command;

وكنت الرجوع إلى نوع TextGame.Commands.ACommand. لأنك إخفاء الملكية بارام في فئة فرعية الخاص بك، وأنت مما تسبب في إشارة غير متعددة الأشكال. إزالة التعريف، والاعتماد على تعريف الفئة الأساسية من بارام، وسوف يكون على ما يرام.

ولقد كانت فترة من الوقت منذ أن واجهت هذه المشكلة، ولكن إذا فتح هذا حتى في العاكس أتوقع سترى أنك إخفاء الملكية Use.Params وراء callvirt ملزمة صراحة إلى نوع قاعدتها هناك .... كما أشارت الطابعين أسرع بها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top