c# 当对象存储在链表中时访问对象/对象方法

c# Accessing an Object / Object Method when the Object is stored in a linked list

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

    }
}

我很快 运行 你的代码,我想我已经解决了你的问题。您需要在 "object" 上进行查找和替换并将其替换为 "Block" 或者您需要将从 getLast 函数返回的对象转换为 "Block".

更改示例如下所示:

LinkedList<Block> chain;

...

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

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

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

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

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

原因是,如果您创建一个通用 "object" 链表,那么在编译时 C# 不知道链表中可能包含什么。它可能是 Blocks,也可能是 Bananas,因此它不知道每个对象可以调用哪些函数和方法。因此,为了让 C# 知道我们必须在从列表中获取项目后使用 "as Block" 强制转换它,或者在您的情况下,只需将链接中所有值的类型设置为 "Block" 就像看起来一样您的程序不会在列表中包含通用条目。

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

当您将链指定为

LinkedList<object> chain

您是在告诉编译器链变量是一个包含对象 class 或对象的任何后代的链表。

因此根据您对链的定义,以下代码是合法的

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

你不能调用 calculateHash() 因为不幸的是,我们的字符串、字典、长颈鹿和整数 classes 不知道如何处理这样的方法调用。

相反,链应声明为

LinkedList<Block> chain;

这意味着链只能包含 Block 类型的元素(或 Block 的后代 class)。

虽然代码中没有显示对这些方法的调用,但您需要将 createGenesisBlock()getLatestBlock() 方法更改为 return 块而不是对象,因为您是不允许再将任何对象添加到您的链接列表中,它必须是一个块。