Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.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# 单例实例不重写和空getter setter_C# - Fatal编程技术网

C# 单例实例不重写和空getter setter

C# 单例实例不重写和空getter setter,c#,C#,名称仅在Main中获取一个值,但不在public plname中,但问题是我不希望人们使用Main,他们使用public plname如下,并且覆盖也不起作用,有人能帮我吗 public class Singleton<T> where T : new() { public static readonly T Api = new T(); protected Singleton() { Console.WriteLine("Inited"); } } public c

名称仅在Main中获取一个值,但不在
public plname
中,但问题是我不希望人们使用Main,他们使用
public plname
如下,并且覆盖也不起作用,有人能帮我吗

public class Singleton<T> where T : new()
{
    public static readonly T Api = new T();
    protected Singleton() { Console.WriteLine("Inited"); }
}
public class SomeSingleton : Singleton<SomeSingleton>
{
    public string Name { get; set; }
    public SomeSingleton() { }
    public virtual string getPluginName() { return Name; }
}
public class plname : SomeSingleton
{
    public plname() { // this not works
        Name = "test";
    }
    public static void Main(string[] args)
    {
        Api.Name = "testing"; // this works
        Console.WriteLine(Api.getPluginName());
        Console.ReadLine();
    }
    public override string getPluginName()
    {
        return "this not works"; // this not works
    }
}  

Main
方法中,
Api
指的是
Singleton.Api
,该方法是(间接)继承自
Singleton
的类型中的方法。这是类型为
Singleton
的静态成员。因此,它显然不是
SomeSingleton
plname
的新成员

由于
Api
现在是
Singleton
的成员,这意味着它只能初始化一次。此时,它将获得值
newt()
,其中
T
SomeSingleton

这意味着,除非您主动更改
Api
中存在的实例,否则它将始终引用相同的
SomeSingleton
实例,该实例在没有任何数据(也没有名称)的情况下被实例化

这就是为什么只执行
Api.getPluginName()
,就会得到
null
:因为
SomeSingleton
的静态实例从未初始化过名称。由于该实例显然不是
plname
的实例,因此
plname
的重写方法也将不适用

因此,您将不得不接受这样一个事实:继承单例通常不会真正起作用,因为对原始类型的单例引用不会被神奇地更新

假设您想编写某种插件系统,那么在不依赖于单例的情况下编写插件系统可能是一个更好的主意。或者,也可以只使用一个单例,允许您在某个注册表中注册插件


这方面的一个例子如下:

public interface IPlugin
{
    string Name { get; }
    void DoStuff();
}

public static class PluginRegistry
{
    private static readonly List<IPlugin> plugins = new List<IPlugin>();
    public static IEnumerable<IPlugin> GetPlugins() => plugins;
    public static void Register(IPlugin plugin) => plugins.Add(plugin);
}

// And then an example plugin implementation
public class MyPlugin : IPlugin
{
    public string Name => "My fancy plugin";
    public void DoStuff() => Console.WriteLine("My fancy plugin was called!");
}
然后您可以使用
PluginRegistry
访问您的插件:

foreach (var plugin in PluginRegistry.GetPlugins())
    plugin.DoStuff();

// Output:
// My fancy plugin was called!

你说的“这不起作用”是什么意思?请详细说明问题是什么,错误消息是什么(如果有)以及您正在努力解决的问题。我已经添加了我想要它的方式,这不起作用意味着Name的值不是我编写的字符串“不是我编写的字符串”是什么意思?为属性
名称
指定一个值,但不要在其他任何地方使用它。请编辑您的问题以包含一个。
Api。getPluginName()
将从静态属性
Api
中的对象返回
Name
属性。但是你已经设置为“测试”。为什么不使用MEF或其他插件系统,你能给我一个例子吗?是的,这是一个插件系统没有办法设置
名称
值,因为我不想写我自己的插件系统这是一个创建自己插件的api方法是DllExported我能与你联系并向你展示完整的项目吗?
PluginRegistry.Register(new MyPlugin());
foreach (var plugin in PluginRegistry.GetPlugins())
    plugin.DoStuff();

// Output:
// My fancy plugin was called!