简体   繁体   English

C#结构/查找表

[英]C# Struct / Lookup Table

Say I have a struct declared like the following: 说我有一个声明如下的结构:

public struct Test
{
    public static int Width = 5;
    ...
    public static int[] Value = new int[1]{ 0 };
}

Now what I want to do is call this from within another struct, but I have to clue how. 现在我想做的是在另一个结构中调用它,但是我必须知道如何做。 What I'm trying to do would (in my mind) look like the following: 我正在尝试做的事情(在我看来)如下所示:

public struct AnotherStruct
{
    public (type of struct) this[int key]
    {
        get
        {
            switch(key)
            {
                case 1:
                    return (another struct);
                default:
                    return null;
            }
        }
    }
}

My end goal is that I want to use code that looks like the following, without having to create an instance of the object: 我的最终目标是,我希望使用如下所示的代码,而不必创建该对象的实例:

structobject s = new AnotherStruct[5];

So this 'lookup table' will be created in another project and built, then called as a dll from my main project. 因此,此“查找表”将在另一个项目中创建并构建,然后从主项目中调用为dll。 Since I'm building the dll elsewhere and calling it, I'm hoping that I can get the dll loaded into memory once, and then I can just reference that memory from my main project. 由于我正在其他地方构建该dll并对其进行调用,因此希望可以将dll一次加载到内存中,然后可以从我的主项目中引用该内存。 Then I'll have one allocated portion of memory and my code will just reference it, avoiding the need to create individual instances of this lookup table (thus avoiding the time overhead it takes to allocate the memory and store the new instance). 然后,我将为内存分配一个部分,而我的代码将只引用它,而无需创建该查找表的各个实例(从而避免了分配内存和存储新实例所需的时间开销)。 The time I'd save would be hugely beneficial in the long run, so I'm hoping I can get this to work somehow. 从长远来看,我节省的时间将极大地有益,所以我希望我可以以某种方式使它起作用。

I hope this isn't too confusing, but let me know if any clarification is needed. 我希望这不要太令人困惑,但请告诉我是否需要澄清。

Edit This is being used on a website, so really I need an object that persists across all connections and is created once when the code is initially loaded. 编辑这是在网站上使用的,因此,实际上,我需要一个在所有连接中均保持不变的对象,并在最初加载代码时创建一次。 Same idea, but maybe that will make for a simpler solution? 相同的想法,但是也许这将使解决方案更简单?

Solution #1. 解决方案#1。 Using a common interface for all the structures and a dictionary collection 对所有结构和词典集合使用通用接口

public interface IStr { }

public struct St1 : IStr
{
    public static int ID = 1;
}
public struct St2 : IStr
{
    public static int ID = 2;
}

public class StructFactory : System.Collections.ObjectModel.KeyedCollection<int, IStr>
{
    public static StructFactory Default = new StructFactory();
    protected override int GetKeyForItem(IStr item)
    {
        FieldInfo finfo = item.GetType().GetField("ID", 
            BindingFlags.Static | BindingFlags.Public);

        return (int)finfo.GetValue(item);
    }

    public StructFactory()
    {
        Add(new St1());
        Add(new St2());
    }
}

class Program
{
    static void Main(string[] args)
    {
        St1 x = (St1)StructFactory.Default[1];
        St2 y = (St2)StructFactory.Default[2];
    }
}

The syntax you use above won't work since it means "create an array of AnotherStruct with five elements in it." 您上面使用的语法不起作用,因为它的意思是“创建一个包含五个元素的AnotherStruct数组”。 As mentioned in a comment, however, you really should look into using a factory pattern. 但是,正如评论中提到的那样,您确实应该考虑使用工厂模式。

However, if you really want to use the pattern above, you could change it up slightly. 但是,如果您确实要使用上面的模式,则可以对其稍加更改。 Have your AnotherStruct array hold Type instances of each of your structs. 让AnotherStruct数组保存每个结构的Type实例。 Then, your "creation" line would look more like: 然后,您的“创建”行将更像:

structobject s = (structobject)Activator.CreateInstance(AnotherStruct[5]);

You can use reflection on the Assembly (since you are wrapping it in a DLL) to get those Type objects. 您可以在Assembly上使用反射(因为您将其包装在DLL中)来获取那些Type对象。

And finally, unless you have a really good reason for using struct (and understand all of the nuances, of which there are several), stick with class . 最后,除非您有充分的理由使用struct (并了解所有细微差别,其中有许多细微差别),否则请坚持使用class

Solution #2. 解决方案2。 Forgo the whole ID idea and just use the structure type and generics. 放弃整个ID的想法,只使用结构类型和泛型即可。

public struct St1 
{
}
public struct St2 
{
}

public class Factory<T>
    where T : struct
{
    static T _new = new T(); //cached copy of structure

    public static T New { get { return _new; } }        
}


class Program
{
    static void Main(string[] args)
    {
        St1 x1 = Factory<St1>.New;
        St1 x2 = Factory<St1>.New;
        St1 x3 = Factory<St1>.New;
        St2 y1 = Factory<St2>.New;
        St2 y2 = Factory<St2>.New;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM