c # Доступ к объекту / метод объекта, когда объект хранится в связанном списке - PullRequest
0 голосов
/ 25 апреля 2018

Предполагается, что это приложение является своего рода демонстрацией того, как работает блокчейн. У меня есть класс цепочки блоков и класс блоков, и класс программы является основным. В классе блокчейна я создаю начальный блок, называемый блоком gensis, в методе createGenesisBlock (). В конструкторе моего класса блокчейна я вызываю метод createGenesisBlock () и вставляю объект в мой связанный список, который называется цепочкой. У меня проблема, когда объект добавляется в связанный список в моем классе блокчейна, я не могу получить доступ к объекту или методам. То, что я пытаюсь сделать, это использовать мой метод getLatestBlock () в классе blockchain, чтобы получить значение хэша последнего объекта, который был помещен в цепочку. Таким образом, возможность вызывать мой метод addBlock в блокчейне, устанавливая значение previousHash, равное значению хэша объекта в связанном списке

namespace BlockChainProject
{
    class Program
    {
        static void Main(string[] args)
        {
            Blockchain blockChain = new Blockchain();
            blockChain.addBlock();
            blockChain.display();
            Console.ReadKey();
        }
    }
}

namespace BlockChainProject
{

    class Block
    {
        private int index;
        private string timeStamp;
        private string data;
        private string previousHash;
        private string hash;


        public Block(int index, string timeStamp, string data, string previousHash) {
            this.index = index;
            this.timeStamp = timeStamp;
            this.data = data;
            this.previousHash = previousHash;
            this.hash = this.calculateHash();
        }

        public string calculateHash() {
            SHA256Managed hashString = new SHA256Managed();
            byte[] dataArray = hashString.ComputeHash(Encoding.UTF8.GetBytes(index.ToString() + previousHash + timeStamp + data));
            StringBuilder stringBuilder = new StringBuilder();
            foreach (byte x in dataArray)
            {
                stringBuilder.AppendFormat("{0:X2}", x);
            }

            string hashed = stringBuilder.ToString();
            return hashed;
        }

        public string getHash() {
            return hash;
        }
    }

}

namespace BlockChainProject
{
    class Blockchain
    {
        LinkedList<object> chain;
        private int index = 0;
        private string time = DateTime.Now.ToString();

        public Blockchain(){
            chain = new LinkedList<object>();
            chain.AddLast(createGenesisBlock());
        }

        private object createGenesisBlock() {
            index++;
            return new Block(index, time, "Genesis Block", "0"); ;
        }

        public object getLatestBlock() {
            return chain.Last.Value;
        }

        public void addBlock() {
            string data = Console.ReadLine();
            //string previousHash = <The hash of linked lists last object here>;
            chain.AddLast(new Block(index, time, data, previousHash));
            index++;

        }

        public void display() {
            foreach (var item in chain)
            {
                Console.WriteLine(item);
            }
        }

    }
}

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Когда вы указываете свою цепь как

LinkedList<object> chain

Вы говорите компилятору, что переменная цепочки является связанным списком, который содержит класс объекта или любого потомка объекта.

Следовательно, следующий код допустим по вашему определению цепочки

chain.Add("Hi there!");
chain.Add(new Dictionary<int, decimal>());
chain.Add(new Giraffe());
chain.Add(42);

Вы не можете вызвать calculateHash(), потому что, к сожалению, наши классы string, Dictionary, Giraffe и int не будут знать, что делать с таким вызовом метода.

Вместо этого цепочка должна быть объявлена ​​как

LinkedList<Block> chain;

Это означает, что цепочка может содержать только элементы типа Block (или потомок класса Block).

Хотя вызовы этих методов не показаны в коде, вам нужно будет изменить методы createGenesisBlock() и getLatestBlock(), чтобы они возвращали Block, а не object, потому что вы не можете добавлять какой-либо объект в связанный объект. список больше, это должен быть блок.

0 голосов
/ 25 апреля 2018

Я быстро запустил твой код и думаю, что понял твою проблему.Вам нужно выполнить поиск и замену в «объекте» и заменить его на «Блок», или в качестве альтернативы вам необходимо привести объекты, возвращаемые из функции getLast, к «Блоку».

Примеризменения будут выглядеть так:

LinkedList<Block> chain;

...

public Block getLatestBlock() {
    return chain.Last.Value;
}

Это некоторые примеры изменений, которые должны быть внесены в класс Blockchain, могут быть и другие, но я не могупомните.

Теперь, когда вы вызываете функцию отображения, у вас есть доступ к функциям и методам каждого из экземпляров класса Block в связанном списке, например, так:

public void display()
{
    foreach (var item in chain)
    {
        Console.WriteLine(item.getHash());
    }
}

Теперь это будетраспечатать список хэшей при условии, что вы изменили все возвращаемые значения, типы и экземпляры, в которых вы использовали объект в связанном списке, на Block.

Причина этого в том, что вы создаете связанный список универсального объекта.s тогда во время компиляции C # понятия не имеет, что может быть в связанных списках.Это могут быть блоки или бананы, поэтому он не знает, какие функции и методы будут доступны для вызова каждому объекту.Таким образом, чтобы C # знал, что мы должны либо привести его с использованием «as Block» после того, как мы получим элемент из списка, либо в вашем случае просто установить тип всех значений в связанном, как «Block», как это выглядит в вашей программеу вас не будет общих записей в списке.

Надеюсь, это ответит на ваш вопрос.Если нет, дайте мне знать.

...