【问题标题】:c# Accessing an Object / Object Method when the Object is stored in a linked listc#当对象存储在链表中时访问对象/对象方法
【发布时间】:2018-04-24 22:28:20
【问题描述】:

这个应用程序应该是一种区块链如何工作的演示。我有一个块链类和一个块类,程序类是主要的。在区块链类中,我在 createGenesisBlock() 方法中创建了一个名为 gensis 块的初始块。在我的区块链类的构造函数中,我调用 createGenesisBlock() 方法并将对象插入我的链表中,该链表称为链。我遇到的问题是当对象被添加到我的区块链类中的链表时,我无法访问该对象或方法。我想要完成的是在区块链类中使用我的 getLatestBlock() 方法来检索放入链中的最后一个对象的哈希值。因此能够在区块链中调用我的 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);
            }
        }

    }
}

【问题讨论】:

    标签: c# hash linked-list blockchain


    【解决方案1】:

    我快速运行了您的代码,我认为我已经解决了您的问题。您需要对“object”进行查找和替换并将其替换为“Block”,或者您需要将 getLast 函数返回的对象转换为“Block”。

    更改示例如下所示:

    LinkedList<Block> chain;
    

    ...

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

    这是对区块链类进行更改的一些示例,可能还有其他更改,但我不记得了。

    现在,当您调用显示函数时,您可以访问链表中每个 Block 类实例的函数和方法,如下所示:

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

    如果您将链接列表中使用对象的所有返回值、类型和实例更改为 Block,现在将打印哈希列表。

    这样做的原因是,如果您创建一个通用“对象”的链表,那么在编译时 C# 不知道链表中可能包含什么。它可能是 Blocks,也可能是 Bananas,所以它不知道每个对象可以调用哪些函数和方法。因此,要让 C# 知道,我们必须在从列表中获取项目后使用“as Block”进行转换,或者在您的情况下,只需按照程序的外观将链接中的所有值的类型设置为“Block”您不会在列表中添加通用条目。

    希望这能回答您的问题。如果不告诉我。

    【讨论】:

    • 是的,这回答了我的问题,非常感谢你,我不知道我可以告诉链接列表是块类型,你的解释很有帮助!
    【解决方案2】:

    当你将你的链指定为

    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 而不是对象,因为您不允许将任何对象添加到您的链接不再列出,它必须是一个块。

    【讨论】:

    • 您的两个答案都为我解决了这个问题,谢谢,我不知道我可以告诉链表它可以阻止我只是假设对象将是我需要使用的东西,非常感谢跨度>
    猜你喜欢
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    相关资源
    最近更新 更多