亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何創建在封閉構造泛型類型的實例之間共享的靜態變量?

如何創建在封閉構造泛型類型的實例之間共享的靜態變量?

PHP
ITMISS 2024-01-21 10:04:50
我希望能夠擁有這個通用類:public class MyClass<T>{  static public string SharedString;}其中SharedString將是一個靜態值,對于封閉構造類型的所有實例都具有相同的值。因此這些實例:var instanceInt = new MyClass<int>();var instanceString = new MyClass<string>();字段將具有相同的值SharedString。例如,如果我寫:instanceInt.SharedString = "Text 1";instanceString.SharedString = "Text 2";那我想要那個instanceInt.SharedString == "Text 2"。在 C# 中,SharedString所有 的實例具有相同的值,但與的實例MyClass<int>不同。SharedStringMyClass<string>所以instanceInt.SharedString == "Text 1"。我希望能夠重用這個概念來創建任何具有任何真正的通用靜態字段的類,該字段可以是aspublic或。privateinternal我讀到了這一點,但它是不夠的,因為我不想每次需要共享值時都重復代碼:在不同的泛型類實例之間共享靜態字段我不想為每個泛型類型創建一個基類,也不想為嵌套或包裝類創建一個基類:它太費力、太重而且不能分解。我只是希望能夠定義幾個通用開放類型并在其中放入一些共享靜態變量。如何解決這個通用多態性缺陷?
查看完整描述

2 回答

?
隔江千里

TA貢獻1906條經驗 獲得超10個贊

我認為有 3 種方法適合您:

  1. 創建一個包含共享字段的非通用基類

  2. 創建一個包含共享字段的非通用單獨類

  3. 創建一個保存這些共享值的非泛型類型,并在泛型類型中重用它

對于第三個,既然你說你并不真正想要選項 1 或 2,那么這里有一個例子:

public abstract class Shared

{

    private readonly static Dictionary<Guid, object> _Variables

        = new Dictionary<Guid, object>();


    protected void SetValue<T>(Guid key, T value)

    {

        lock (_Variables)

            _Variables[key] = value;

    }


    protected T GetValue<T>(Guid key)

    {

        object temp;

        lock (_Variables)

            if (!_Variables.TryGetValue(key, out temp))

                return default;


        return (T)temp;

    }

}


public class Shared<T> : Shared

{

    private readonly Guid _Key;


    public Shared(Guid key)

    {

        _Key = key;

    }


    public T Value

    {

        get => GetValue<T>(_Key);

        set => SetValue<T>(_Key, value);

    }

}

你可以像這樣使用它:


public class MyClass<T>

{

    private static readonly Shared<string> _Shared

        = new Shared<string>(Guid.Parse("521ecaba-2a5e-43f2-90e0-fda38a32618c"));


    public void Set(string value)

    {

        _Shared.Value = value;

    }


    public void Get()

    {

        Console.WriteLine(_Shared.Value);

    }

}

該 MyClass 的 Set/Get 方法用于測試通過一種封閉類型設置的值是否可通過另一種封閉類型使用,如下所示:


var mc1 = new MyClass<int>();

var mc2 = new MyClass<string>();


mc1.Set("Test");

mc2.Get();

這將輸出Test.


盡管所有封閉類型MyClass<T>都有自己的靜態Shared<T>實例,但該實例中包含的值將由共享字典支持,該字典在使用該Shared<T>類型的所有類型之間共享。


就我個人而言,我建議使用靜態非泛型基類:


public abstract class MyClass

{

    protected static string _Shared;

}


public class MyClass<T> : MyClass

{

    public void Set(string value)

    {

        _Shared = value;

    }


    public void Get()

    {

        Console.WriteLine(_Shared);

    }

}

如果您更喜歡“基類”,即保存共享值的類型,不可用,并且與基類關系不大(也不適用于結構),您可以輕松地將其設為一個完全獨立的類:


internal static class MyClassShared

{

    public static string Shared;

}


public class MyClass<T>

{

    public void Set(string value)

    {

        MyClassShared.Shared = value;

    }


    public void Get()

    {

        Console.WriteLine(MyClassShared.Shared);

    }

}


查看完整回答
反對 回復 2024-01-21
?
倚天杖

TA貢獻1828條經驗 獲得超3個贊

這是我的解決方案,源自 @LasseV?gs?therKarlsen

使用指南和字典的想法。

它終于起作用了,而且非常簡單!

我估計他的解決方案的因式分解和可重用性的優勢超過了其他重復代碼和性能降低。

現在可以減少代碼并且更易于維護。

謝謝。

SharedStaticValue 類

public class SharedStaticValue<T>

{


  static private class Collector

  {

    static private readonly object locker = new object();

    static private readonly Dictionary<Guid, object> _Values

        = new Dictionary<Guid, object>();

    static internal void SetValue<T>(Guid key, T value)

    {

      lock ( locker )

        if ( _Values.ContainsKey(key) )

          _Values[key] = value;

        else

          _Values.Add(key, value);

    }

    static internal T GetValue<T>(Guid key)

    {

      lock ( locker )

        if ( _Values.ContainsKey(key) )

          return (T)_Values[key];

        else

        {

          T value = default(T);

          _Values.Add(key, value);

          return value;

        }

    }

  }


  private readonly Guid ID;


  public T Value

  {

    get { return Collector.GetValue<T>(ID); }

    set { Collector.SetValue(ID, value); }

  }


  public override string ToString()

  {

    return Value.ToString();

  }


  public SharedStaticValue(Guid id)

  {

    ID = id;

  }


}

考試

public class GenericClass<T>

{

  static public int Value

  {

    get { return _Value.Value; }

    set { _Value.Value = value; }

  }

  static private SharedStaticValue<int> _Value

    = new SharedStaticValue<int>(Guid.Parse("521ecaba-2a5e-43f2-90e0-fda38a32618c"));

}


internal class Class1 : GenericClass<int>

{

}


internal class Class2 : GenericClass<string>

{

}


internal class SharedStaticValueTest

{

  private SharedStaticValue<int> value 

    = new SharedStaticValue<int>(Guid.Parse("{E838689A-3B2C-4BFB-A15C-2F1B5D65F1DE}"));

  public void RunTest()

  {

    Action<string> write = (str) =>

    {

      Console.WriteLine(str);

      Console.WriteLine("  this.SharedStaticValue<int> = " + value.Value);

      Console.WriteLine("  GenericClass<double> = " + GenericClass<double>.Value);

      Console.WriteLine("  GenericClass<int> = " + GenericClass<int>.Value);

      Console.WriteLine("  Class1 extend GenericClass<int> = " + Class1.Value);

      Console.WriteLine("  Class2 extend GenericClass<string> = " + Class2.Value);

      Console.WriteLine();

    };

    write("Default values");

    value.Value = 10;

    write("Set this.SharedStaticValue<int>.Value = 10");

    GenericClass<double>.Value = 20;

    write("Set GenericClass<double>.Value = 20");

    GenericClass<int>.Value = 30;

    write("Set GenericClass<int>.Value = 30");

    Class1.Value = 40;

    write("Set Class1 extend GenericClass<int>.Value = 40");

    Class2.Value = 50;

    write("Set Class2 extend GenericClass<string>.Value = 50");

  }

}

輸出

Default values

  this.SharedStaticValue<int> = 0

  GenericClass<double> = 0

  GenericClass<int> = 0

  Class1 extend GenericClass<int> = 0

  Class2 extend GenericClass<string> = 0


Set this.SharedStaticValue<int>.Value = 10

  this.SharedStaticValue<int> = 10

  GenericClass<double> = 0

  GenericClass<int> = 0

  Class1 extend GenericClass<int> = 0

  Class2 extend GenericClass<string> = 0


Set GenericClass<double>.Value = 20

  this.SharedStaticValue<int> = 10

  GenericClass<double> = 20

  GenericClass<int> = 20

  Class1 extend GenericClass<int> = 20

  Class2 extend GenericClass<string> = 20


Set GenericClass<int>.Value = 30

  this.SharedStaticValue<int> = 10

  GenericClass<double> = 30

  GenericClass<int> = 30

  Class1 extend GenericClass<int> = 30

  Class2 extend GenericClass<string> = 30


Set Class1 extend GenericClass<int>.Value = 40

  this.SharedStaticValue<int> = 10

  GenericClass<double> = 40

  GenericClass<int> = 40

  Class1 extend GenericClass<int> = 40

  Class2 extend GenericClass<string> = 40


Set Class2 extend GenericClass<string>.Value = 50

  this.SharedStaticValue<int> = 10

  GenericClass<double> = 50

  GenericClass<int> = 50

  Class1 extend GenericClass<int> = 50

  Class2 extend GenericClass<string> = 50


查看完整回答
反對 回復 2024-01-21
  • 2 回答
  • 0 關注
  • 208 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號