简体   繁体   English

“存储”一个类型参数供以后在C#中使用?

[英]“Store” a type parameter for later use in C#?

I'm creating a Settings object in my app, used for storing user-defined settings and whatnot. 我正在应用程序中创建一个Settings对象,用于存储用户定义的设置等。 I plan on using various datatypes for my setting fields (ints, strings, enums, anything Serializable, really). 我计划在我的设置字段中使用各种数据类型(int,字符串,枚举,任何可序列化的东西)。

I'd also like, if possible, a type-safe way to set any of the settings. 如果可能的话,我还想使用一种类型安全的方式来设置任何设置。 My proposed method would be doing something like this: 我建议的方法将执行以下操作:

Tuple<string, Type> SettingName = new Tuple<string, Type>("NumberOfFoos",
                                                          typeof(**TYPE**));
public void Set(Tuple<string, Type> key, **TYPE** value) { /* Stuff */ }

The Tuple would effectively be the "setting" that the user would push a value to, and would consist of the key for that setting as well as the type of that setting. 元组实际上是用户将值推入的“设置”,并且将由该设置的键以及该设置的类型组成。 What I'm wondering is if there's any way to have the compiler enforce that, in the Set() method, the type of value is of the same type as the type object saved in the tuple passed to Set() ? 我想知道的是,是否有任何方法可以让编译器强制执行以下操作:在Set()方法中, value的类型与保存在传递给Set()的元组中的类型对象的类型相同? Is the way I proposed even possible? 我提出的方法是否可行? Thanks! 谢谢!

EDIT: I thought of some more things I should clarify. 编辑:我想到了一些我应该澄清的事情。

1) This is intended to be a static class, so I won't be able to serialize the whole class, only members in it. 1)这打算是一个静态类,所以我将无法序列化整个类,只能序列化其中的成员。 Therefore, I'd really like to not have to deal with a serialization for each field. 因此,我真的很想不必处理每个字段的序列化。 I was planning on storing all the setting values in a Dictionary<string, **TYPE**> and serializing that. 我打算将所有设置值存储在Dictionary<string, **TYPE**>并对其进行序列化。

2) The Tuple definitions are meant to be constant and static. 2) Tuple定义是恒定的和静态的。 I'm really treating them as more of a typedef-type thing (I really should make my own SettingKey struct), which the user passes to Set to indicate what field they are changing. 我实际上将它们更多地视为typedef类型的东西(我确实应该创建自己的SettingKey结构),用户将其传递给Set来指示它们正在更改的字段。 The Type parameter is meant to enforce the the value parameter is of the specified type. Type参数用于强制value参数为指定类型。

Something like 就像是

public void Set<T>(Tuple<string,T> key, T value) { /* stuff */ }

might do it 可能会做到

It's better to get rid of the tuple, and use a generic method: 最好删除元组,并使用通用方法:

public void Set<T>(string key, T value);

That way, you can specify the type at compile-time 这样,您可以在编译时指定类型

Set<string>("MyStringKey", "foo");
Set<int>("MyIntKey", 1);

or the compiler can infer it for you: 或编译器可以为您推断:

Set("MyStringKey", "foo");
Set("MyIntKey", 1);

and in Set , you can use typeof(T) to get the Type object you would have passed in. Set ,可以使用typeof(T)来获取要传递的Type对象。

Why not simply add strongly typed properties to your settings object? 为什么不简单地将强类型属性添加到您的设置对象? eg public int NumberOfFoos {get {} set {...}} and in the getter and setter call your common serialization and deserialization code. 例如public int NumberOfFoos {get {} set {...}}并在getter和setter中调用您的通用序列化和反序列化代码。

If you do this your settings object isn't exposing how it works internally and you have full intellisense support on it. 如果这样做,您的设置对象将无法公开其内部工作方式,并且您将获得全面的智能感知支持。

Well, if you did something like Set<T>(Tuple<string, T>, T value) , you'd get what you're after for setting. 好吧,如果您执行了诸如Set<T>(Tuple<string, T>, T value)类的操作,则将获得设置所需的内容。 And I think the compiler could infer the T in Set<T>() at usage, so you would have to write it. 而且我认为编译器可以在使用时推断Set<T>()中的Set<T>() ,因此您必须编写它。

But your Get<T>() , you'd have to specify the type you expected to get back. 但是,您的Get<T>() ,您必须指定期望返回的类型。

public class Foo
{
  Tuple<string, Type> SettingName = new Tuple<string, Type>("NumberOfFoos",
                                                          typeof(**TYPE**));
  public void Set(Tuple<string, Type> key, object value) 
  {
    if(value.GetType() != SettingsName.Value)
      throw new ArgumentException("value");
  }
}

You would be better of using generics like in the other answers though. 不过,最好像其他答案一样使用泛型。

I don't think you need to deal with Type s at all. 我认为您根本不需要处理Type Would something like this be good enough? 这样的东西够好吗?

class Settings {
  public static int Foo { 
    get { return (int)_map["Foo"]; }
    set { _map["Foo"] = value; }
  }
  public static string Bar {
    get { return (string)_map["Foo"]; }
    set { _map["Foo"] = value; }
  }
  // ...
  private static Dictionary<string, object> _map = 
    new Dictionary<string, object>();
}

You'd then serialize the dictionary. 然后,您将序列化字典。 You could even use some code-generation to create this class. 您甚至可以使用一些代码生成来创建此类。

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

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