【问题标题】:Why do I get an error instantiating an abstract class?为什么我在实例化抽象类时会出错?
【发布时间】:2019-09-07 00:50:36
【问题描述】:

我下载了一个名为Process.NETNuGet 包,并尝试在main() 函数中使用IMemory 接口中的Read() 方法。我在GIT 教程中实现了它,但我无法像这样创建ProcessMemory 的实例:

ProcessMemory memory = new ProcessMemory();

我收到此错误:

"Unable to create instance of the abstract class or interface 'ProcessMemory'. "

我找到了一些关于此的线索,但还没有任何帮助。这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Process.NET.Memory;
using Process.NET.Native.Types;

namespace MemoryHacker
{
    class Program
    {
        static void Main(string[] args)
        {

            ProcessMemory memory = new ProcessMemory();

        }
    }

    //Class with Read() function
    public abstract class ProcessMemory : IMemory
    {
        protected readonly SafeMemoryHandle Handle;

        protected ProcessMemory(SafeMemoryHandle handle)
        {
            Handle = handle;
        }

        public abstract byte[] Read(IntPtr intPtr, int length);

        public string Read(IntPtr intPtr, Encoding encoding, int maxLength)
        {
            var buffer = Read(intPtr, maxLength);
            var ret = encoding.GetString(buffer);
            if (ret.IndexOf('\0') != -1)
                ret = ret.Remove(ret.IndexOf('\0'));
            return ret;
        }

        public abstract T Read<T>(IntPtr intPtr);

        public T[] Read<T>(IntPtr intPtr, int length)
        {
            var buffer = new T[length];
            for (var i = 0; i < buffer.Length; i++)
                buffer[i] = Read<T>(intPtr);
            return buffer;
        }

        public abstract int Write(IntPtr intPtr, byte[] bytesToWrite);

        public void Write(IntPtr intPtr, string stringToWrite, Encoding encoding)
        {
            if (stringToWrite[stringToWrite.Length - 1] != '\0')
                stringToWrite += '\0';
            var bytes = encoding.GetBytes(stringToWrite);
            Write(intPtr, bytes);
        }


        public void Write<T>(IntPtr intPtr, T[] values)
        {
            foreach (var value in values)
                Write(intPtr, value);
        }

        public abstract void Write<T>(IntPtr intPtr, T value);
    }

}

编辑:好的,实例化的事情现在很清楚了。但我仍然收到错误:

"No argument was specified that corresponds to the formal handle parameter of ProcessMemory.ProcessMemory (SafeMemoryHandle)."

看看上面的代码有什么想法吗?

EDIT2:您需要解决这个问题的所有内容都在下面的答案中说明。只是一点提示,如果您使用Visual Studio,然后右键单击新类,然后单击实现。它为你写了很多东西!

【问题讨论】:

标签: c# interface abstract-class implementation


【解决方案1】:

我不熟悉这个包,我也不清楚你想要达到什么目的,所以我真的不知道我可以如何帮助你,但我可以告诉你:

抽象类不应该被实例化。

您要么必须删除 abstract 关键字,要么创建自己的类,这样实现抽象类:

public class MyProcessMemory : ProcessMemory
{
    public override byte[] Read(IntPtr intPtr, int length)
    {
        throw new NotImplementedException();
    }

    public override T Read<T>(IntPtr intPtr)
    {
        throw new NotImplementedException();
    }

    public override int Write(IntPtr intPtr, byte[] bytesToWrite)
    {
        throw new NotImplementedException();
    }

    public override void Write<T>(IntPtr intPtr, T value)
    {
        throw new NotImplementedException();
    }
}

无论哪种情况,您都必须自己实现抽象函数。 希望这会有所帮助

【讨论】:

  • 谢谢,我学到了很多。我从来没有真正确定抽象类和接口。不幸的是,我尝试了它并再次遇到错误。这次它的“没有指定与 ProcessMemory.ProcessMemory (SafeMemoryHandle) 的正式句柄参数相对应的参数”。 - 有什么建议吗?
  • @Bush_Did_911 你需要满足抽象类中的构造函数。它期待一个SafeMemoryHandle 参数。像MyProcessMemory(SafeMemoryHandle handle) : base(handle) { } 这样的东西会起作用
【解决方案2】:

您不能直接使用抽象类。您可以在创建派生自这些的新类时使用它们

【讨论】:

    【解决方案3】:

    您不能实例化抽象类。抽象类的目的是为派生类提供一个通用接口。抽象类没有明确需要为任何方法提供实现(请注意标记为abstract 的方法缺少主体),因为预计子类提供大部分实现。阅读文档以了解哪个子类最适合您的需求并对其进行实例化。

    【讨论】:

      【解决方案4】:

      您不能直接实例化抽象类,您需要创建另一个实现它的类,并通过完成基类中标记为abstract的任何方法来提供完整的实现。你的情况是:

      byte[] Read(IntPtr intPtr, int length)
      
      T Read<T>(IntPtr intPtr)
      
      int Write(IntPtr intPtr, byte[] bytesToWrite)
      
      void Write<T>(IntPtr intPtr, T value)
      

      以下链接可以帮助您了解更多https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/abstract。与它声明的类有关:

      abstract 修饰符表示被修改的事物有一个 缺少或不完整的实现。

      标记为抽象或包含在抽象类中的成员必须是 由派生自抽象类的类实现。

      【讨论】:

      • 谢谢你!如果我是对的,那么抽象类就像是另一个类的模板,不是吗??
      • 是的没错,它可能提供了一些方法,但你需要填写其余的。
      • 好吧,接口是一个带有声明方法的模板,但实际上它们是空的,并且可以在类中填充代码,对吗?
      • 是的,一个接口完全是空的,你可以实现多个接口但只能从一个类继承(无论是抽象类还是“普通类”)
      • 没问题,这也可能有帮助(有很多赞成票!)stackoverflow.com/questions/761194/…
      猜你喜欢
      • 2011-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 2014-07-12
      • 1970-01-01
      • 2022-07-22
      • 2012-10-29
      相关资源
      最近更新 更多