我想在另一个类中获取Lazy实例,问题是T类型仅在主类中设置
实例所在的第一类是这个
public class singleton<T> where T : class, new()
{
private readonly static Lazy<T> val = new Lazy<T>(() => new T());
public static T instance { get { return val.Value; } }
public int UserID {get;set;}
}
现在我还有一个用于所有用户数据的类
public class User
{
public string Name()
{
return data.GetUserFromID(singleton.instance.UserID)
}
}
单例不起作用,因为我需要参数,但是T仅在主类中
public class main : singleton<main>
{
public main()
{
UserID = 5;
}
}
编辑
如何从另一个这样的类中的单例类获取ID
单例文件
public class singleton<T> where T : class, new()
{
private readonly static Lazy<T> val = new Lazy<T>(() => new T());
public static T instance { get { return val.Value; } }
public int UserID {get;set;}
private singleton() {
Datas.UserID = UserID;
}
}
另一个文件
public class Datas {
public static int UserID {get;set;}
}
答案 0 :(得分:0)
单例不起作用,因为我需要参数,但T仅在主类中
您需要做的就是从以下位置更改代码:
public class User {
public string Name() {
return data.GetUserFromID(singleton.instance.UserID)
}
}
...以指定通用类型参数:
public class User
{
public string Name()
{
var m = singleton<main>.instance;
Console.WriteLine($"Inside User.Name, m.UserId = {m.UserID}");
return "todo";
}
}
这是必需的,因为您的客户代码正在直接访问通用库。如果您将其封装到工厂经理或类似人员中,则客户无需指定类型。
这里有一些测试工具
private void Run()
{
var x = singleton<main>.instance;
Console.WriteLine($"x.UserId = {x.UserID}");
var y = singleton<main>.instance;
Console.WriteLine($"y.UserId = {y.UserID}");
x.UserID++;
Console.WriteLine($"x.UserId = {x.UserID}");
Console.WriteLine($"y.UserId = {y.UserID}");
var user = new User();
Console.WriteLine($"User.Name = {user.Name()}");
var mp = MissPiggy.Instance;
}
将产生以下结果。请注意,更改两个不同变量的属性会如何修改相同的单例。
实现单例的方式也存在一些问题。单例类应具有private
构造函数,并且应该是一个管理生命周期的构造函数,而不是辅助类。
例如
public sealed class MissPiggy
{
private static Lazy<MissPiggy> _instance = new Lazy<MissPiggy>(() => new MissPiggy());
private MissPiggy()
{
}
public static MissPiggy Instance
{
get { return _instance.Value; }
}
}
答案 1 :(得分:0)
singleton<t>
是通用类型-没有通用类型参数,您将无法引用它。
实际上,它实际上是在生成新类型。
因此,当您这样做时:
var mainSingleton = singleton<main>.instance;
它实际上是在创建一个新的类型,如下所示:
public class NewGenericTypeWithWeirdName
{
private readonly static Lazy<main> val = new Lazy<main>(() => new main());
public static main instance { get { return val.Value; } }
public int UserID { get; set; }
}
...并且,如果您声明var otherSingleton = singleton<SomethingElse>.instance;
,它也会做同样的事情-它会创建与上面相同的另一种类型,只是将T
替换为SomethingElse
。
这就是为什么您不能这样做:
singleton.instance.UserID
因为编译器不知道您指的是哪种类型。它是为singleton<main>
生成的类型,还是为singleton<SomethingElse>
生成的类型?它们实际上是不同的类型,这意味着它们的静态属性(包括UserID
)将有所不同。
您可以这样做:
return data.GetUserFromID(singleton<main>.instance.UserID);
^^^^^^
...因为现在您要告诉它实际的类型-它是singleton<main>
。
请澄清一下,除非该类具有private
构造函数且没有非私有构造函数,否则它不是单例。
您可以这样做:
var mainSingleton = singleton<main>.instance;
,它将始终返回main
的相同实例。
但是您也可以这样做:
var m1 = new singleton<main>();
var m2 = new singleton<main>();
您可以创建多个实例,因此不是一个实例。要解决此问题,请将私有构造函数添加到singleton
:
private singleton(){}
现在只能在类中调用构造函数。这意味着获取实例的唯一方法是调用instance
。每次执行此操作时,您都会得到一个相同的实例,所以现在它确实是一个单例。