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()