C# 泛型类的静态成员是否绑定到特定实例?
这与其说是一个真正的问题,不如说是一个文档。这似乎还没有得到解决(除非我错过了),因此: 设想一个包含静态成员的泛型类:C# 泛型类的静态成员是否绑定到特定实例?,c#,.net,generics,static,C#,.net,Generics,Static,这与其说是一个真正的问题,不如说是一个文档。这似乎还没有得到解决(除非我错过了),因此: 设想一个包含静态成员的泛型类: class Foo<T> { public static int member; } class-Foo{ 公共静态int成员; } 每个特定类是否有一个新的成员实例,或者所有Foo类型类是否只有一个实例 可以很容易地通过以下代码进行验证: Foo<int>.member = 1; Foo<string>.member = 2;
class Foo<T> {
public static int member;
}
class-Foo{
公共静态int成员;
}
每个特定类是否有一个新的成员实例,或者所有Foo类型类是否只有一个实例
可以很容易地通过以下代码进行验证:
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
Foo.member=1;
Foo.member=2;
Console.WriteLine(Foo.member);
结果是什么?这种行为记录在哪里?它们不是共享的。不确定记录在哪里,但分析警告(不要在泛型类型上声明静态成员)警告不要这样做,因为这样会使代码更加复杂。它们不共享。不确定它记录在哪里,但是分析警告(不要在泛型类型上声明静态成员)警告不要这样做,因为这样会使代码更加复杂。IMO,您需要测试它,但我认为
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
Foo.member=1;
Foo.member=2;
Console.WriteLine(Foo.member);
将输出1
,因为我认为在编译期间,编译器会为您使用的每个泛型类创建一个类(在您的示例中:Foo
和Foo
)
但我不是100%肯定=)
备注:我认为使用此类静态属性既不是一个好的设计,也不是一个好的实践。IMO,您需要对其进行测试,但我认为
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
Foo.member=1;
Foo.member=2;
Console.WriteLine(Foo.member);
将输出1
,因为我认为在编译期间,编译器会为您使用的每个泛型类创建一个类(在您的示例中:Foo
和Foo
)
但我不是100%肯定=)
备注:我认为使用此类静态属性既不是一个好的设计,也不是一个好的实践。a
static
字段在相同类型的所有实例中共享Foo
和Foo
是两种不同的类型。这可以通过以下代码行证明:
// this prints "False"
Console.WriteLine(typeof(Foo<int>) == typeof(Foo<string>));
//这会打印“False”
控制台写入线(typeof(Foo)==typeof(Foo));
关于记录的地方,在C语言规范(针对C#3)的第1.6.5节字段中可以找到以下内容:
静态字段正好标识一个
存储位置。不管有多少
创建类的实例,
一本书只有一本
静态场
如前所述Foo
和Foo
不是同一类;它们是由同一泛型类构造的两个不同类。上述文件第4.4节概述了这一过程:
泛型类型声明本身,
表示一个未绑定的泛型类型
被用作“蓝图”,形成许多
不同类型,通过应用
类型参数
静态
字段在同一类型的所有实例中共享Foo
和Foo
是两种不同的类型。这可以通过以下代码行证明:
// this prints "False"
Console.WriteLine(typeof(Foo<int>) == typeof(Foo<string>));
//这会打印“False”
控制台写入线(typeof(Foo)==typeof(Foo));
关于记录的地方,在C语言规范(针对C#3)的第1.6.5节字段中可以找到以下内容:
静态字段正好标识一个
存储位置。不管有多少
创建类的实例,
一本书只有一本
静态场
如前所述Foo
和Foo
不是同一类;它们是由同一泛型类构造的两个不同类。上述文件第4.4节概述了这一过程:
泛型类型声明本身,
表示一个未绑定的泛型类型
被用作“蓝图”,形成许多
不同类型,通过应用
类型参数
它们不是真正共享的。 因为成员根本不属于实例。 静态类成员属于类本身。 因此,如果您有MyClass.Number,则所有MyClass.Number对象都是相同的,因为它甚至不依赖于对象。 您甚至可以在没有任何对象的情况下调用或修改MyClass.Number 但是由于Foo
TestClass<string>.Number = 5;
TestClass<int>.Number = 3;
Console.WriteLine(TestClass<string>.Number); //prints 5
Console.WriteLine(TestClass<int>.Number); //prints 3
TestClass.Number=5;
TestClass.Number=3;
Console.WriteLine(TestClass.Number)//印刷品5
Console.WriteLine(TestClass.Number)//印刷品3
它们不是真正共享的。
因为成员根本不属于实例。
静态类成员属于类本身。
因此,如果您有MyClass.Number,则所有MyClass.Number对象都是相同的,因为它甚至不依赖于对象。
您甚至可以在没有任何对象的情况下调用或修改MyClass.Number
但是由于FooTestClass<string>.Number = 5;
TestClass<int>.Number = 3;
Console.WriteLine(TestClass<string>.Number); //prints 5
Console.WriteLine(TestClass<int>.Number); //prints 3
TestClass.Number=5;
TestClass.Number=3;
Console.WriteLine(TestClass.Number)//印刷品5
Console.WriteLine(TestClass.Number)//印刷品3
这里的问题实际上是“泛型类”根本不是类
泛型类定义只是类的模板,在指定其类型参数之前,它们只是一段文本(或少量字节)
在运行时,可以为模板指定一个类型参数,从而使其生效,并创建一个完全指定类型的类。这就是为什么静态属性不是全模板的,这就是为什么不能在List
和List
之间转换
这种关系有点像类-对象关系。就像类在实例化对象之前不存在一样,泛型类也不存在,直到基于它们创建一个类