【问题标题】:Does the C# standard library have a generic class for storing a mutable value?C# 标准库是否有用于存储可变值的通用类?
【发布时间】:2015-08-20 04:34:09
【问题描述】:

我需要一个类来存储可变值。当这个类的一个实例在不同的代码部分之间共享并且一个部分更改了该对象内的值时,所有其他部分都会看到新值。

这个问题不是我能写出来的。任何人都可以在这里搜索:

public class ValueHolder<T> { public T Value { get; set; } }

我的问题是,这个类是否存在于标准库中的任何地方?这感觉就像它提供的许多小类中包含的东西。

或者,有没有另一种方法可以实现我所要求的结果,而不会在我的代码中乱扔小类?

更新/评论:
我对这个问题提出的消极程度感到有点惊讶。
“这导致WTF计数很高!” “你在重新发明!”

在提出这个问题时,我明确提出要避免重新发明。如果标准库中已经有一些东西,我可以使用它而不是编写一个新类。 (只要收益大于成本。)

传递对象并允许对其进行修改的技术一直在使用。你有没有写过一个函数,它需要一个 List 以便该函数添加/删除值?允许事件处理程序通过在 event-args 对象中设置值来更改正在进行的事件的事件处理程序(例如 Form.Closing)呢?

在我的例子中,对象只是一个类,其中包含一个布尔值。它被传递到另一段代码中,以允许升高或降低该标志。您可能会说这应该是函数的返回值或 ref 参数,但我使用的框架允许将对象传递给处理程序(类似于 ParameterizedThreadStart 或 Tag 属性),所以我的内容有限可以绕过去。

“我想知道标准库是否已经有一个这样做的类。”我心想。 “一起来看看吧!”

【问题讨论】:

  • 为什么不在您打算引用ValueHolder 的类中添加对Value 的引用?
  • 据我所知没有(而且我认为这有点反模式......)。 .通常在 C# 中有更好的方法来处理这些事情(例如 INotifyPropertyChanged 或 Reactive Extensions)
  • 你正在重新发明Tuple&lt;T&gt;。它确实永远落后于door on the right。
  • 请检查右边的门是什么。 ;) 另请注意,这不会编译:var test = Tuple.Create("TEST"); test.Item1 = "New"; 以防万一您正在考虑这样做...
  • 我不想在余生中支持这样的答案。你可以自己贴出答案,至少在大家讨厌的时候你可以再次摆脱它。

标签: c# .net mutable standard-library


【解决方案1】:

您可以通过这种方式使用Tuple。

【讨论】:

    【解决方案2】:

    为了在我的项目中的任何地方以及在我的应用生命周期的任何时间注册和获取对象,我使用惰性对象:

    public static class ServiceContainer
    {
        static readonly Dictionary<Type, Lazy<object>> services = new Dictionary<Type, Lazy<object>>();
    
        public static void Register<T>(Func<T> function)
        {
            services[typeof(T)] = new Lazy<object>(() => function());
        }
    
        public static T Resolve<T>()
        {
            return (T)Resolve(typeof(T));
        }
    
        public static object Resolve(Type type)
        {
            Lazy<object> lazy;
            if (services.TryGetValue(type, out lazy))
                return lazy.Value;
            throw new Exception("Not found!");
        }
    }
    

    为了使用:

    public class Program 
    {
        public void Main()
        {
            ServiceContainer.Register<IFoo>(() => new Foo()); /*register foo*/
        }
    
        public void UsingFoo()
        {
            var foo = ServiceContainer.Resolve<IFoo>(); /* do something with foo... */
        }
    }
    

    你可以在这里找到更多关于惰性对象的信息:

    【讨论】:

      猜你喜欢
      • 2010-11-13
      • 1970-01-01
      • 2019-04-03
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多