Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从静态方法访问继承的成员-单例继承? 问题摘要_C#_Inheritance_Static Methods_Member_Non Static - Fatal编程技术网

C# 从静态方法访问继承的成员-单例继承? 问题摘要

C# 从静态方法访问继承的成员-单例继承? 问题摘要,c#,inheritance,static-methods,member,non-static,C#,Inheritance,Static Methods,Member,Non Static,实际上,我只想使用普通的继承功能。 问题是,我的一些方法是静态的,因此它们无法像普通方法那样访问继承的属性。 此外,我不能将任何内容传递给静态方法(如对象的实例),因为它们是由“外部触发器”调用的。 另一方面,我不需要多个实例,这意味着类似于单例的东西就可以了 让我一步一步地向你解释我的情况: (或者直接跳到第一个代码示例以查看MCV示例) 要求1-访问成员的静态方法 我正在使用该库修补现有程序集的方法。 修补方法必须是静态的,并且由库的“钩子”调用。 我向游戏添加新的玩家升级。对于我要修补的每

实际上,我只想使用普通的继承功能。
问题是,我的一些方法是静态的,因此它们无法像普通方法那样访问继承的属性。 此外,我不能将任何内容传递给静态方法(如对象的实例),因为它们是由“外部触发器”调用的。
另一方面,我不需要多个实例,这意味着类似于单例的东西就可以了

让我一步一步地向你解释我的情况:
(或者直接跳到第一个代码示例以查看MCV示例)

要求1-访问成员的静态方法 我正在使用该库修补现有程序集的方法。 修补方法必须是静态的,并且由库的“钩子”调用。
我向游戏添加新的玩家升级。对于我要修补的每次升级,我都会创建一个包含成员的类,如名称、说明、图像。。。 一次升级只能修补一次,因此这里的解决方案是使所有东西都保持静态。
但是

要求2-继承 因为这些升级共享许多通用成员和方法,所以我创建了一个BaseUpgrade类并从中派生。
现在,每个特定的实现都可以将它们的值分配给公共字段,如名称、描述。。。并继承其余的(使用成员的方法)。
然而,静态修补方法不再能够访问成员。为此,我可以使用单例。
我还想继承所有的单例数据,使其通用化。这样,只有基类拥有所有Sington代码。
一种方法是这样的解决方案:
然而

要求3-具有基类集合 我需要有基类的集合,并在字典中使用它们(作为键和值)。但这似乎不适用于泛型类。
我找到了,但我被卡住了。我不知道这是否真的有效。至少这会使事情变得更加复杂

这样行吗?有没有更简单的方法来解决我的问题


基本场景的MCV示例
使用系统;
使用System.Collections.Generic;
使用单例的名称空间
{
//这是试图导入可继承单例的版本
类Base,其中T:Base,new()
{
#区域单态物质
私有静态T_实例;
公共静态T实例
{
收到
{
if(_instance==null)
_实例=新的T();
返回_实例;
}
set=>_instance=value;
}
#端区
公共字符串名称;//应可由派生类的静态方法访问
公共字符串描述;
保护基()
{
name=“Base”;
}
public void printName()
{
Console.WriteLine(名称);
}
}
类第一子类:基
{
public int number;//应可由类的静态方法访问
公共第一胎()
{
name=“第一个孩子”;
数字=7;
}
公共静态void StaticMethod_FirstChild()
{
WriteLine(“StaticMethod\u FirstChild:我可以访问所有成员变量!:-)”;
Console.WriteLine(“名称:“+Instance.Name+”,编号:“+Instance.Number”);//这项功能正在运行
}
}
第二类:基本类
{
公众持股;
公共第二儿童()
{
name=“第二个孩子”;
myfloat=0.3f;
}
公共静态void StaticMethod_SecondChild()
{
WriteLine(“StaticMethod\u SecondChild:我可以访问所有成员变量!:-)”;
Console.WriteLine(“Name 2x:+Instance.Name+”“+Instance.Name);//现在可以工作了
}
}
类管理器//使用基类的集合管理从“Base”派生的实例/单例
{
//字典项dict;//*******此项现在已损坏
公共经理()
{
//itemDict=新字典();
//碱性添加剂;
//addItem=新的第一个孩子();
//Add(addItem.GetType().Name,addItem);
//addItem=新的第二个子项();
//Add(addItem.GetType().Name,addItem);
//模拟一个静态方法的外部调用
SecondChild.StaticMethod_SecondChild();
Console.WriteLine();
}
公共无效剂量测定法()
{
//foreach(itemDict中的var项)
//{
//item.Value.printName();
//}
}
}
班级计划
{
静态void Main(字符串[]参数)
{
经理=新经理();
经理:DoSomething();
Console.ReadLine();
}
}
}

使用可继承单例的示例
使用系统;
使用System.Collections.Generic;
使用单例的名称空间
{
//这是试图导入可继承单例的版本
类Base,其中T:Base,new()
{
#区域单态物质
私有静态T_实例;
公共静态T实例
{
收到
{
if(_instance==null)
_实例=新的T();
返回_实例;
}
set=>_instance=value;
}
#端区
公共字符串名称;//应可由派生类的静态方法访问
公共字符串描述;
保护基()
{
name=“Base”;
}
public void printName()
{
Console.WriteLine(名称);
}
}
类第一子类:基
{
public int number;//应该可以通过
using System;
using System.Collections.Generic;

namespace Using_Singleton
{

    // This is the version trying to incorperate the inheritable singleton
    class Base<T> where T : Base<T>, new()
    {
        #region Singleton stuff

        private static T _instance;

        public static T Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new T();
                return _instance;
            }
            set => _instance = value;
        }

        #endregion

        public string name;     // Should be accessible by the derived class' static methods
        public string desc;

        protected Base()
        {
            name = "Base";
        }

        public void printName()
        {
            Console.WriteLine(name);
        }
    }

    class FirstChild : Base<FirstChild>
    {
        public int number;      // Should be accessible by the class' static methods

        public FirstChild()
        {
            name = "The first child";
            number = 7;
        }

        public static void StaticMethod_FirstChild()
        {
            Console.WriteLine("StaticMethod_FirstChild: I can access all member variables! :-)");
            Console.WriteLine("Name: " + Instance.name + ", Number: " + Instance.number);     // This is now working
        }

    }

    class SecondChild : Base<SecondChild>
    {
        public float myfloat;

        public SecondChild()
        {
            name = "The second child";
            myfloat = 0.3f;
        }

        public static void StaticMethod_SecondChild()
        {
            Console.WriteLine("StaticMethod_SecondChild: I can access all member variables! :-)");
            Console.WriteLine("Name 2x: " + Instance.name + " " + Instance.name);       // This is now working
        }
    }

    class Manager       // Manages instances/singletons which derive from "Base" by using a collection of the Base class
    {
        //Dictionary<string, Base> itemDict;        // ******* This is now broken

        public Manager()
        {
            //itemDict = new Dictionary<string, Base>();

            //Base addItem;

            //addItem = new FirstChild();
            //itemDict.Add(addItem.GetType().Name, addItem);

            //addItem = new SecondChild();
            //itemDict.Add(addItem.GetType().Name, addItem);

            // Simulating the external call of one static method
            SecondChild.StaticMethod_SecondChild();
            Console.WriteLine();
        }

        public void DoSomething()
        {
            //foreach (var item in itemDict)
            //{
            //  item.Value.printName();
            //}
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Manager manager = new Manager();
            manager.DoSomething();

            Console.ReadLine();
        }
    }

}
using System;
using System.Collections.Generic;

namespace Using_Singleton
{

    // This is the version trying to incorperate the inheritable singleton
    class Base<T> where T : Base<T>, new()
    {
        #region Singleton stuff

        private static T _instance;

        public static T Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new T();
                return _instance;
            }
            set => _instance = value;
        }

        #endregion

        public string name;     // Should be accessible by the derived class' static methods
        public string desc;

        protected Base()
        {
            name = "Base";
        }

        public void printName()
        {
            Console.WriteLine(name);
        }
    }

    class FirstChild : Base<FirstChild>
    {
        public int number;      // Should be accessible by the class' static methods

        public FirstChild()
        {
            name = "The first child";
            number = 7;
        }

        public static void StaticMethod_FirstChild()
        {
            Console.WriteLine("StaticMethod_FirstChild: I can access all member variables! :-)");
            Console.WriteLine("Name: " + Instance.name + ", Number: " + Instance.number);     // This is now working
        }

    }

    class SecondChild : Base<SecondChild>
    {
        public float myfloat;

        public SecondChild()
        {
            name = "The second child";
            myfloat = 0.3f;
        }

        public static void StaticMethod_SecondChild()
        {
            Console.WriteLine("StaticMethod_SecondChild: I can access all member variables! :-)");
            Console.WriteLine("Name 2x: " + Instance.name + " " + Instance.name);       // This is now working
        }
    }

    class Manager       // Manages instances/singletons which derive from "Base" by using a collection of the Base class
    {
        //Dictionary<string, Base> itemDict;        // ******* This is now broken

        public Manager()
        {
            //itemDict = new Dictionary<string, Base>();

            //Base addItem;

            //addItem = new FirstChild();
            //itemDict.Add(addItem.GetType().Name, addItem);

            //addItem = new SecondChild();
            //itemDict.Add(addItem.GetType().Name, addItem);

            // Simulating the external call of one static method
            SecondChild.StaticMethod_SecondChild();
            Console.WriteLine();
        }

        public void DoSomething()
        {
            //foreach (var item in itemDict)
            //{
            //  item.Value.printName();
            //}
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Manager manager = new Manager();
            manager.DoSomething();

            Console.ReadLine();
        }
    }
}
using System;
using System.Collections.Generic;

namespace Using_Singleton_And_GenericCollection
{
    // This is the version trying to incorperate the inheritable singleton and a generic collection

    abstract class NonGenericBase       // Adding this (class or interface) make the use of collections possible.
    {
        public string name;
        public string desc;

        public void printName()
        {
            Console.WriteLine("\t" + name);
        }

        protected NonGenericBase() { }
    }

    class Base<T> : NonGenericBase where T : Base<T>, new()
    {
        #region Singleton stuff

        protected static T _instance;

        public static T Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new T();
                return _instance;
            }
            set => _instance = value;
        }

        #endregion

        //public string name;     // Moved to parent
        //public string desc;

        protected Base()
        {
            name = "Base";
        }
    }


    class FirstChild : Base<FirstChild>
    {
        public int number;      // Should be accessible by the class' static methods

        public FirstChild()
        {
            name = "The first child";
            number = 7;
        }

        public static void StaticMethod_FirstChild()
        {
            Console.WriteLine("\tStaticMethod_FirstChild: I can access all member variables! :-)");
            Console.WriteLine("\tName: " + Instance.name + ", Number: " + Instance.number);     // This is now working
        }
    }

    class SecondChild : Base<SecondChild>
    {
        public float myfloat;

        public SecondChild()
        {
            name = "The second child";
            myfloat = 0.3f;
        }

        public static void StaticMethod_SecondChild()
        {
            Console.WriteLine("\tStaticMethod_SecondChild: I can access all member variables! :-)");
            Console.WriteLine("\tName 2x: " + Instance.name + ", " + Instance.name);       // This is now working
        }
    }


    class Manager       // Manages instances/singletons which derive from "Base" by using a collection of the Base class
    {
        public Dictionary<string, NonGenericBase> itemDict;

        public Manager()
        {
            itemDict = new Dictionary<string, NonGenericBase>();

            NonGenericBase addItem;

            addItem = FirstChild.Instance;
            itemDict.Add(addItem.GetType().Name, addItem);

            addItem = SecondChild.Instance;
            itemDict.Add(addItem.GetType().Name, addItem);
        }

        public void DoSomething()
        {
            foreach (var item in itemDict)
            {
                item.Value.printName();
            }
            Console.WriteLine();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            var sec = new SecondChild();

            Console.WriteLine("Access Singletons");
            Manager manager = new Manager();
            manager.DoSomething();

            Console.WriteLine("Change Singletons");
            manager.itemDict[nameof(FirstChild)].name = "first name changed";
            SecondChild.Instance.name = "second name changed too";
            manager.DoSomething();

            Console.WriteLine("Create and change a non-Singleton instance of FirstChild");
            var initItem = new FirstChild();
            initItem.printName();
            initItem.name = "Non-Singleton name changed";
            initItem.printName();
            Console.WriteLine();

            Console.WriteLine("Access Singletons");
            manager.DoSomething();

            Console.WriteLine("Call static method of FirstChild");
            FirstChild.StaticMethod_FirstChild();         //Simulating the external call of one static method
            Console.WriteLine();

            Console.ReadKey();
        }
    }
} 
class Base<T> : NonGenericBase where T : Base<T>, new()