泛型:T的强制类型初始化 [英] Generics: force type initialiser of T

查看:99
本文介绍了泛型:T的强制类型初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定T的通用方法,是否有一种确保T上的任何静态ctor执行的好方法?下面的代码演示了(TestClass1)

通过泛型,你可以在静态

ctor激发之前使用Type实例。


使用泛型类和new()我可以在泛型类的

静态ctor中强制执行此操作,但这并不总是方便的,

加上可能(可能?)被视为不 - op [不确定]。


样本;理想情况下,我会得到Static ctor 1。在类型名称之前输出

为1(按照第二次测试),不使用任何黑客......


Marc


使用System;

class Prog {

static void Main(){

GenMethod< TestClass1>();

GenClass< TestClass2> .Method();

}

static void GenMethod< T>(){

Console.WriteLine(" GenMethod" + typeof(T).FullName);

}

}

class GenClass< Twhere T: new()

{

static GenClass(){//可能设置noinlining

new T(); // 丢弃;强制T'的静态ctor

}

public static void Method(){

Console.WriteLine(" Method:" + typeof(T).FullName);

}

}

class TestClass1 {

static TestClass1(){

Console.WriteLine(" Static ctor 1");

}

}

class TestClass2 {

static TestClass2(){

Console.WriteLine(" Static ctor 2");

}

}

Given a generic method "of T", is there a good way of ensuring that any
static ctor on T has executed? Following code demonstrates (TestClass1)
that via generics you can use the Type instance long before the static
ctor fires.

With a generic class and the "new()" clause, I can force this in the
static ctor of the generic class, but this is not always convenient,
plus may (possibly?) be seen as a no-op [not sure here].

Sample; ideally I''d get "Static ctor 1" to output before the type-name
of 1 (as per the second test), without using any hacks...

Marc

using System;
class Prog {
static void Main() {
GenMethod<TestClass1>();
GenClass<TestClass2>.Method();
}
static void GenMethod<T>() {
Console.WriteLine("GenMethod" + typeof(T).FullName);
}
}
class GenClass<Twhere T : new()
{
static GenClass() { // possibly set noinlining
new T(); // throw away; forces T''s static ctor
}
public static void Method() {
Console.WriteLine("Method: " + typeof(T).FullName);
}
}
class TestClass1 {
static TestClass1() {
Console.WriteLine("Static ctor 1");
}
}
class TestClass2 {
static TestClass2() {
Console.WriteLine("Static ctor 2");
}
}

推荐答案

给定一个通用方法T,是否有一种确保
Given a generic method "of T", is there a good way of ensuring that

T上的任何静态ctor都已执行?以下代码演示了

(TestClass1),通过泛型,您可以在静态ctor触发之前使用Type实例long




使用泛型类和new()我可以在泛型类的

静态ctor中强制执行此操作,但这并不总是方便的,

加上可能(可能?)被视为不 - op [不确定]。


样本;理想情况下,我会得到Static ctor 1。在类型名称之前输出

为1(根据第二次测试),不使用任何黑客...
any static ctor on T has executed? Following code demonstrates
(TestClass1) that via generics you can use the Type instance long
before the static ctor fires.

With a generic class and the "new()" clause, I can force this in the
static ctor of the generic class, but this is not always convenient,
plus may (possibly?) be seen as a no-op [not sure here].

Sample; ideally I''d get "Static ctor 1" to output before the type-name
of 1 (as per the second test), without using any hacks...



嗯。 ..我还没有办法做到这一点。你不能用反射来做这个因为不允许调用类型初始化器。例如,这个

失败:


static GenClass()

{

ConstructorInfo staticConstructor = typeof(T)。GetConstructor(BindingFlags.Static

| BindingFlags.NonPublic,null,Type.EmptyTypes,null);

staticConstructor.Invoke(null);

}


但是,类型初始化器保证在以需要初始化的方式访问类型时为
。所以,你可以通过反射调用一个虚拟的

静态方法:


使用System;

使用System.Reflection ;


班级课程

{

static void Main()

{

GenMethod< TestClass1>();

GenClass< TestClass2> .Method();

}

static void GenMethod< T> ;()

{

Console.WriteLine(" GenMethod" + typeof(T).FullName);

}

}

类GenClass< Twhere T:new()

{

static GenClass()

{

MethodInfo dummyMethod = typeof(T).GetMethod(" DummyMethod",BindingFlags.Static

| BindingFlags.NonPublic,null,Type.EmptyTypes,null);

dummyMethod.Invoke(null,null);

}

public static void Method()

{

Console.WriteLine(" Method:" + typeof(T).FullName);

}

}

类TestClass 1

{

static void DummyMethod(){}

static TestClass1()

{

Console.WriteLine(" Static ctor 1");

}

}

class TestClass2

{

static void DummyMethod(){}

static TestClass2()

{

Console.WriteLine (静态ctor 2);

}

}


我的大问题是,你为什么要这样做这个?如果你试图以某种确定的方式调用类型

初始化器,那么可能需要一个不同的设计。

表示你​​需要一个不同的设计。 />

最诚挚的问候,

Dustin Campbell

Developer Express Inc.

Hmmm... I haven''t found a way to do this. You can''t use reflection to do
this because invoking a type initializer is disallowed. For example, this
fails:

static GenClass()
{
ConstructorInfo staticConstructor = typeof(T).GetConstructor(BindingFlags.Static
| BindingFlags.NonPublic, null, Type.EmptyTypes, null);
staticConstructor.Invoke(null);
}

However, the type initializers is guaranteed to be when the type is accessed
in such a way that initialization is required. So, you could have a dummy
static method that is called via reflection:

using System;
using System.Reflection;

class Program
{
static void Main()
{
GenMethod<TestClass1>();
GenClass<TestClass2>.Method();
}
static void GenMethod<T>()
{
Console.WriteLine("GenMethod" + typeof(T).FullName);
}
}
class GenClass<Twhere T: new()
{
static GenClass()
{
MethodInfo dummyMethod = typeof(T).GetMethod("DummyMethod", BindingFlags.Static
| BindingFlags.NonPublic, null, Type.EmptyTypes, null);
dummyMethod.Invoke(null, null);
}
public static void Method()
{
Console.WriteLine("Method: " + typeof(T).FullName);
}
}
class TestClass1
{
static void DummyMethod() { }
static TestClass1()
{
Console.WriteLine("Static ctor 1");
}
}
class TestClass2
{
static void DummyMethod() { }
static TestClass2()
{
Console.WriteLine("Static ctor 2");
}
}

My big question is, why do you want to do this? If you''re trying to get type
initializers to be called in some sort of deterministic way, it might be
an indication that you need a different design.

Best Regards,
Dustin Campbell
Developer Express Inc.


这或多或少都在我的地方......我会避免反思,但是b $ b虽然 - 看起来有点混乱:但是也要感谢所有。


为什么是复杂的,并且涉及使用

查找注册一些接口(字典映射接口到实现

接口的实例),以供使用,例如通过一些通用的延迟加载,其中物件

进行加载 (即未初始化的订单集合)知道

如何获取其接口方面的数据(供应商/适配器为
想要一个更好的术语),但不是''知道谁(哪个特定班级)

将提供数据。在我应用new()之前在一些

测试用例中,没有一个类在lazy查找时及时注册自己作为提供者,所以它失败了(优雅地)。


通过修复,事情正确地说嘿,我存在并且可以做

< x>...


主要目标是进行延迟加载,如果它不关心
是否有直接(SqlClient)或间接(WSDL等)访问数据 -

长,因为具体类正确地符合界面。


当然,如果你想引用一个模式来看待它?


Marc

That is more or less where I got to... I''ll avoid the reflection,
though - seems a bit scrappy : but thanks all the same.

The why is complex, and relates to registering a few interfaces with a
lookup (dictionary mapping interfaces to instances implementing that
interface), for use e.g. by some generic lazy-loading, where the "thing
doing the loading" (i.e. an uninitialised collection of orders) knows
how to get its data in terms of interfaces (providers / adapters for
want of a better term), but doesn''t know who (which specific class)
will be providing the data. Until I applied the "new()" bit, in a few
test cases no class was registering itself as the provider in time for
the lazy lookup, so it was failing (gracefully).

With the fix, things are correctly saying "hey, I exist and can do
<x>"...

The main objective is to do lazy loading where it doesn''t care if it
has direct (SqlClient) or indirect (WSDL etc) access to the data - as
long as the concrete class meets the interface correctly.

Of course, if you care to cite a pattern to look at?

Marc


我知道这有点好,但是:


class TestClass2 {

public static bool Initialized = false;

static TestClass2(){

Initialized = true;

Console.WriteLine("静态ctor 2);

}

}


我想知道这是否可用......


彼得

-

联合创始人,Eggheadcafe.com开发者门户网站:
http://www.eggheadcafe.com

UnBlog:
I know this is kinda hokey, but:

class TestClass2 {
public static bool Initialized=false;
static TestClass2() {
Initialized=true;
Console.WriteLine("Static ctor 2");
}
}

I wonder if that would be usable...

Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"Marc Gravell" wrote:

给定一个通用方法T,是否有一种很好的方法可以确保T上的任何静态ctor都有执行?下面的代码演示了(TestClass1)

通过泛型,你可以在静态

ctor激发之前使用Type实例。


使用泛型类和new()我可以在泛型类的

静态ctor中强制执行此操作,但这并不总是方便的,

加上可能(可能?)被视为不 - op [不确定]。


样本;理想情况下,我会得到Static ctor 1。在类型名称之前输出

为1(按照第二次测试),不使用任何黑客......


Marc


使用System;

class Prog {

static void Main(){

GenMethod< TestClass1>();

GenClass< TestClass2> .Method();

}

static void GenMethod< T>(){

Console.WriteLine(" GenMethod" + typeof(T).FullName);

}

}

class GenClass< Twhere T: new()

{

static GenClass(){//可能设置noinlining

new T(); // 丢弃;强制T'的静态ctor

}

public static void Method(){

Console.WriteLine(" Method:" + typeof(T).FullName);

}

}

class TestClass1 {

static TestClass1(){

Console.WriteLine(" Static ctor 1");

}

}

class TestClass2 {

static TestClass2(){

Console.WriteLine(" Static ctor 2");

}

}

Given a generic method "of T", is there a good way of ensuring that any
static ctor on T has executed? Following code demonstrates (TestClass1)
that via generics you can use the Type instance long before the static
ctor fires.

With a generic class and the "new()" clause, I can force this in the
static ctor of the generic class, but this is not always convenient,
plus may (possibly?) be seen as a no-op [not sure here].

Sample; ideally I''d get "Static ctor 1" to output before the type-name
of 1 (as per the second test), without using any hacks...

Marc

using System;
class Prog {
static void Main() {
GenMethod<TestClass1>();
GenClass<TestClass2>.Method();
}
static void GenMethod<T>() {
Console.WriteLine("GenMethod" + typeof(T).FullName);
}
}
class GenClass<Twhere T : new()
{
static GenClass() { // possibly set noinlining
new T(); // throw away; forces T''s static ctor
}
public static void Method() {
Console.WriteLine("Method: " + typeof(T).FullName);
}
}
class TestClass1 {
static TestClass1() {
Console.WriteLine("Static ctor 1");
}
}
class TestClass2 {
static TestClass2() {
Console.WriteLine("Static ctor 2");
}
}


这篇关于泛型:T的强制类型初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆