繁体   English   中英

如何通过 C# 中的代码中定义的变量名称查找对数组的引用?

[英]How to find a reference to an array by the name of the variable as defined in the code in C#?

显然,我不是在寻找经典:

string[] garden = {"Tulip"};
Console.WriteLine(garden[0]);

而是对字符串做同样的事情:

string[] garden = {"Tulip"};
string gardenname = "garden";
string[] cool_NEW_array = ArrayByName(gardenname);
Console.WriteLine(cool_NEW_array[0])

我很好奇是否存在一些实际存在的“ArrayByName”版本,它可以让我通过使用作为其名称的字符串来查找数组。 提前致谢!

据我所知,这是不可能的,这可能会导致很多关于反射和生成 IL 的问题。

在方法的调用者中有nameof运算符和含义来获取变量名称,但它不适合您的目标。

也许有一些反射工具可以做到这一点,但我不知道。

也许您可以通过解析所有类、所有实例、所有字段和属性成员、所有方法以及这些方法的所有局部变量来对整个程序集使用巨大的反射来做到这一点......

在任何情况下,您都可能会遇到重复词汇的问题。

但是您可以使用以预期变量名称为键的Dictionary

因此,您创建了一种数据表。

我们使用 class 变量作为私有变量来存储一些一维字符串 arrays 和公共方法来添加和删除这些 arrays 以及从集合中找到一个字符串包含的匹配方法(如果需要的话)。

该系列

static private readonly Dictionary<string, string[]> RegisteredArrays 
  = new Dictionary<string, string[]>();

register 和 unbregister 方法

static public void RegisterArray(string name, string[] array)
{
  if ( !RegisteredArrays.ContainsKey(name)
    && !RegisteredArrays.ContainsValue(array) )
    RegisteredArrays.Add(name, array);
}

static public void UnregisterArray(string name)
{
  if ( RegisteredArrays.ContainsKey(name) )
    RegisteredArrays.Remove(name);
}

static public void UnregisterArray(string[] array)
{
  if ( RegisteredArrays.ContainsValue(array) )
  {
    var item = RegisteredArrays.FirstOrDefault(kvp => kvp.Value == array).Key;
    RegisteredArrays.Remove(item);
  }
}

查找方法

static public IEnumerable<string[]> FindRegisteredArray(string name)
{
  foreach ( var item in RegisteredArrays )
    if ( item.Key == name )
      yield return item.Value;
}

测试

static void Test()
{
  string[] garden1 = { "Tulip", "Rose" };
  string[] garden2 = { "Flower 1", "Flower 2", "Flower 3" };

  RegisterArray(nameof(garden1), garden1);
  RegisterArray(nameof(garden2), garden2);

  string gardenname = "garden1";

  foreach ( var array in FindRegisteredArray(gardenname) )
    Console.WriteLine(string.Join(",", array));

  foreach ( var array in FindRegisteredArray("garden2") )
    Console.WriteLine(string.Join(",", array));
}

Output

Tulip,Rose
Flower 1,Flower 2,Flower 3

改进

您可以创建一个完整的 class 来提供所需的行为

static public class NamedStringArrayManager
{
  static private readonly Dictionary<string, string[]> RegisteredArrays
    = new Dictionary<string, string[]>();

  static public void Register(string name, string[] array)
  {
    if ( !RegisteredArrays.ContainsKey(name)
      && !RegisteredArrays.ContainsValue(array) )
      RegisteredArrays.Add(name, array);
  }

  static public void Unregister(string name)
  {
    if ( RegisteredArrays.ContainsKey(name) )
      RegisteredArrays.Remove(name);
  }

  static public void Unregister(string[] array)
  {
    if ( RegisteredArrays.ContainsValue(array) )
    {
      var item = RegisteredArrays.FirstOrDefault(kvp => kvp.Value == array).Key;
      RegisteredArrays.Remove(item);
    }
  }

  static public IEnumerable<string[]> Find(string name)
  {
    foreach ( var item in RegisteredArrays )
      if ( item.Key == name )
        yield return item.Value;
  }
}
static void Test()
{
  string[] garden1 = { "Tulip", "Rose" };
  string[] garden2 = { "Flower 1", "Flower 2", "Flower 3" };

  NamedStringArrayManager.Register(nameof(garden1), garden1);
  NamedStringArrayManager.Register(nameof(garden2), garden2);

  string gardenname = "garden1";

  foreach ( var array in NamedStringArrayManager.Find(gardenname) )
    Console.WriteLine(string.Join(",", array));

  foreach ( var array in NamedStringArrayManager.Find("garden2") )
    Console.WriteLine(string.Join(",", array));
}

我们还可以为任何类型创建通用管理器

static public class NamedInstanceManager<T>
{
  static private readonly Dictionary<string, T> RegisteredArrays
    = new Dictionary<string, T>();

  static public void Register(string name, T instance)
  {
    if ( !RegisteredArrays.ContainsKey(name)
      && !RegisteredArrays.ContainsValue(instance) )
      RegisteredArrays.Add(name, instance);
  }

  static public void Unregister(string name)
  {
    if ( RegisteredArrays.ContainsKey(name) )
      RegisteredArrays.Remove(name);
  }

  static public void Unregister(T instance)
  {
    if ( RegisteredArrays.ContainsValue(instance) )
    {
      var item = RegisteredArrays.FirstOrDefault(kvp => kvp.Value.Equals(instance)).Key;
      RegisteredArrays.Remove(item);
    }
  }

  static public IEnumerable<T> Find(string name)
  {
    foreach ( var item in RegisteredArrays )
      if ( item.Key == name )
        yield return item.Value;
  }
}

或者只是任何 object:

static public class NamedInstanceManager
{
  static private readonly Dictionary<string, object> RegisteredArrays
    = new Dictionary<string, object>();

  static public void Register(string name, object instance)
  {
    if ( !RegisteredArrays.ContainsKey(name)
      && !RegisteredArrays.ContainsValue(instance) )
      RegisteredArrays.Add(name, instance);
  }

  static public void Unregister(string name)
  {
    if ( RegisteredArrays.ContainsKey(name) )
      RegisteredArrays.Remove(name);
  }

  static public void Unregister(object instance)
  {
    if ( RegisteredArrays.ContainsValue(instance) )
    {
      var item = RegisteredArrays.FirstOrDefault(kvp => kvp.Value.Equals(instance)).Key;
      RegisteredArrays.Remove(item);
    }
  }

  static public IEnumerable<object> Find(string name)
  {
    foreach ( var item in RegisteredArrays )
      if ( item.Key == name )
        yield return item.Value;
  }
}

我们还可以管理注册和取消注册相同引用的多个不同名称等...通过抛出异常、返回布尔值或什么都不做。

此处代码仅接受添加名称或引用,前提是两者都不在集合中。

暂无
暂无

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

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