简体   繁体   English

我如何创建一个 object 作为稍后放置的数据(例如整数)的“合同”?

[英]How can I create an object which acts as a “contract” for data (e.g an integer) to be placed there later?

I'm populating an object[] with items of different types - eg [string, int, DateTime].我正在用不同类型的项目填充对象 [] - 例如 [string, int, DateTime]。 Some values depend on data that only becomes available later (in real-time).某些值取决于仅在以后(实时)可用的数据。 I would like to create a "contract" for this data in the array, and then later when the data is available, swap out the "contract" object for the actual data.我想在数组中为这个数据创建一个“合同”,然后当数据可用时,将“合同”object 换成实际数据。 So if it is a Contract, then I can change the Contract to a string later on.因此,如果它是一个合同,那么我可以稍后将合同更改为一个字符串。 I am using the term "contract" here in a unique way, not necessarily relevant to any other uses of the term that you may be familiar with.我在这里以一种独特的方式使用术语“合同”,不一定与您可能熟悉的该术语的任何其他用途相关。 I'm open to dropping this term if it becomes confusing, it just helped me conceptualize my use case.如果它变得令人困惑,我愿意放弃这个术语,它只是帮助我概念化我的用例。

At first I tried overloading the int cast operator:起初我尝试重载 int cast 运算符:

// Expected types: string, int, DateTime
object[] Item = new object[] { 
    "hello", new Contract<int>(), DateTime.Now()
}

public class Contract<T>
{
    public static implicit operator int(Contract<T> Contract)
    {
        // Here the data would be actually resolved
        return 0;
    }
}

However, in the client code (in a referenced assembly I have no control over) where object[] Item is used, I get the following error: expected System.Int32 but found Namespace.Contract `1[System.Int32] .但是,在使用object[] Item的客户端代码(在我无法控制的引用程序集中)中,出现以下错误: expected System.Int32 but found Namespace.Contract `1[System.Int32] Apparently, the client code expects an Int32 value but receives an Int32 boxed inside a Contract, if I understand this error message (I might not).显然,如果我理解此错误消息(我可能不理解),客户端代码需要一个 Int32 值,但会收到一个装在合同内的 Int32。

One way I thought of trying to do this was:我想尝试这样做的一种方法是:

// Expected types: string, int, DateTime
object[] Item = new object[] { 
    "hello", new Contract<int>(), DateTime.Now()
}

// Interface to allow creating a List of generics
public interface IContract {}

List<IContract> Contracts = new List<IContract>();

public class Contract<T> : IContract
{
    public Contract()
    {
        Contracts.Add(this);
    }    

    public static implicit operator int(Contract<T> Contract)
    {
        // Here the data would be actually resolved
        return 0;
    }
}

// And later on
foreach (var Contract in Contracts)
{
    Contract = (int)(Contract<int>)Contract;
}

But for obvious reasons foreach iteration variables are immutable.但是由于明显的原因 foreach 迭代变量是不可变的。

The difficulty is that when the client code comes to evaluate the contents of the array, it expects an integer but finds a boxed value.困难在于,当客户端代码来评估数组的内容时,它需要一个 integer 但找到一个装箱值。 If it was dynamic, it would still encounter a Contract object rather than the int it expects.如果它是动态的,它仍然会遇到 Contract object 而不是它期望的 int。 I overloaded the int cast operator in hopes that it would perform a cast to the type it expects, but it does not.我重载了 int 类型转换操作符,希望它能转换成它期望的类型,但事实并非如此。 I really need some way of either a) automatically unboxing the type when the client code evaluates it or b) manually unboxing the type myself just beforehand.我真的需要某种方法,要么a)在客户端代码评估类型时自动取消装箱,要么b)自己事先手动取消装箱。

Any ideas on how to proceed?关于如何进行的任何想法? I'm open to changing to a different pattern entirely.我愿意完全改变为不同的模式。 The thought of initializing the object[] without the correct data in the first place seems misguided.首先在没有正确数据的情况下初始化 object[] 的想法似乎被误导了。 If there is a better way to resolve the array data at the time the data becomes available, I'm interested.如果在数据可用时有更好的方法来解析数组数据,我很感兴趣。

Changed direction a little and now have a workable solution.稍微改变了方向,现在有了一个可行的解决方案。

// First, got rid of the complicated generic and interface
public class Contract
{
    // The target array to modify
    public object[] Target { get; set; }
    // Index to the item in the target array
    public int Index { get; set; }

    public void Resolve()
    {
        // Change the value stored in the target array from Contract to int
        Target[Index] = 0;
    }
}

List<Contract> Contracts = new List<Contract>();

// Expected types: string, int, DateTime
object[] Items = new object[] { 
    "hello", new Contract(), DateTime.Now()
}

// A preprocessing step for Items array
foreach (var Item in Items)
{
    if (Item is Contract)
    {
        var Contract = (Contract)Item;
        Contract.Index = Index;
        Contract.Target = Items;
        Contracts.Add(Contract);
    }
}

// Later
foreach(var Contract in Contracts)
{
    Contract.Resolve();
}

The pre-processing step for Items is the main overhead that results from the change. Items 的预处理步骤是更改导致的主要开销。 The rest is simplified. rest 被简化。 The real implementation is a little more complex and has more detailed requirements than shown here.实际的实现比这里显示的要复杂一些,并且有更详细的要求。 This shows the key concepts for reaching the solution.这显示了达成解决方案的关键概念。 Thank you to commenters for your assistance.感谢评论者的帮助。

暂无
暂无

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

相关问题 如何将c#代码逻辑(if-else-loops)导出到文本文件(例如XML)中,然后再导入回来并运行? - How can I export my c# code logic (if-else-loops) in to text files (e.g XML) and later import it back and run? 我如何在输入数字时删除特殊字符,例如使用 C# 和 Javascript 的 Cardnumber - How can i remove special character when I input a number e.g a Cardnumber Using C# with Javascript 如何在表中用逗号将小数点后的值更改为2,532.00到2532。 - How can i change value in decimal place with comma e.g 2,532.00 to 2532 in my table. 我可以在system.drawing中添加一个控件,例如按钮吗? - can I add a control in system.drawing, e.g a button perhaps? Linq Group by Complex Object(对象的EG列表元素) - Linq Group by Complex Object (E.G list element of object) 我可以以原始形式(例如包括引号)获取我的申请的论据吗? - Can I get the arguments to my application in the original form (e.g including quotes)? 如何将易碎数据(例如,连接字符串)从一个控制器传递到另一个 - How to pass fragile data e.g connection string from one controller to another 我是否应该多余地测试参数(例如集合空度)? - Should I redundantly test arguments (e.g collection emptiness)? byte[] 值如何转换为例如结构? - How byte[] values are converted to e.g struct? 如何创建受运行时变量影响的自定义属性? (例如PrincipalPermissionAttribute) - How do I create a custom attribute which is affected by runtime variables? (e.g. PrincipalPermissionAttribute)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM