C# 中的泛型类成员?

发布于 2024-08-16 17:24:22 字数 614 浏览 6 评论 0原文

嘿,我想我的想法是错误的,但我不确定什么是最好的。我想要一个带有成员变量的类,该变量可以是任何类型,具体取决于当时的需要。到目前为止,我有这样的内容:

    public class ConfigSetting<T> {
    private T value;

    public T GetValue() {
        return value;
    }
    public void ChangeValue() {

    }

    public ConfigSetting(string heading, string key) {
        this.value = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
    }
}

当前,“this.value”行右侧返回的类型是一个字符串。我知道这里似乎我不需要使用除字符串类型之外的任何东西,但最终我将扩展构造函数,使得“this.value”可以是字符串、int、float 或 bool。

不管怎样,我的编译器说“无法将‘string’转换为‘T’”,所以我认为我正在做一些非常倒退的事情。

谢谢。

Hey, I think I have the wrong idea here, but I'm not sure what is best. I want a class with a member variable that can be of any type, depending on what is needed at the time. So far, I have something like this:

    public class ConfigSetting<T> {
    private T value;

    public T GetValue() {
        return value;
    }
    public void ChangeValue() {

    }

    public ConfigSetting(string heading, string key) {
        this.value = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
    }
}

The type returned by the right side of the 'this.value' line is a string, currently. I know here it seems like I have no need to use anything other than the string type, but eventually I will expand the constructor, such that 'this.value' could be a string, int, float, or bool.

Anyway, my compiler says "Cannot convert 'string' to 'T'", so I assume I'm doing something very backwards.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

海未深 2024-08-23 17:24:22

您遇到了问题,因为这不是泛型的良好使用。如果泛型类型参数只能以四种不同的方式构造——字符串、浮点数、布尔值和整数——那么这就不是很泛型。我希望通用事物可以是任何类型

如果我有一个东西只能是四种类型中的一种,那么我会像这样建模:

abstract class ConfigSetting
{ /* shared code here */  }

class TextSetting : ConfigSetting
{ /* Code here to handle string settings */ }

class BooleanSetting : ConfigSetting
{ /* ... 

依此类推。然后,我可能会为它们每个人提供一个内部构造函数,并使用工厂模式将基类变成派生类的工厂。

仅当您的解决方案确实是通用的时才使用泛型。例如,List 可以是任何东西的列表:整数、字符串、数组、字典、函数等等。如果您正在建模的事物具有少量可能的类型,则只需为每种类型创建一个即可。

You're running into problems because this is not a good use of generics. If the generic type parameter can only be constructed in four different ways -- string, float, bool and int -- then this isn't very generic. I expect that a generic thing can be any type at all.

If I had a thing that could only be one of four types then I would model it like this:

abstract class ConfigSetting
{ /* shared code here */  }

class TextSetting : ConfigSetting
{ /* Code here to handle string settings */ }

class BooleanSetting : ConfigSetting
{ /* ... 

and so on. I would probably then give each of them an internal constructor, and make the base class into a factory for the derived classes, using the factory pattern.

Only use generics if your solution is truly generic. Like List<T>, for example, can be a list of anything: ints, strings, arrays, dictionaries, functions, whatever. If the thing you are modeling has a small number of possible types, just make one for each type.

她说她爱他 2024-08-23 17:24:22

那么,您希望它应用什么转换?如果您希望该值已经是正确的类型,您可以这样做:

object tmp = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
this.value = (T) tmp;

来遍历 object

this.value = (T)(object) DerivedMethods.configsettings... (etc);

请注意,您必须隐式(如此处)或使用显式强制转换 为泛型类型有一定的限制。但如果原始值确实正确,它应该可以工作。

Well, what conversion did you expect it to apply? If you expect the value to already be of the right type, you could do:

object tmp = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
this.value = (T) tmp;

Note that you have to go through object either implicitly (as here) or with an explicit cast:

this.value = (T)(object) DerivedMethods.configsettings... (etc);

The set of conversions provided for generic types is somewhat limited. But it should work if the original value is genuinely correct.

风柔一江水 2024-08-23 17:24:22

您需要将返回的字符串转换为 T

public ConfigSetting(string heading, string key) {
    this.value = (T)DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
}

You need to cast the returned String to T:

public ConfigSetting(string heading, string key) {
    this.value = (T)DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
}
绳情 2024-08-23 17:24:22

我认为您不必使用泛型来提前计划所有可能的未来场景,因为您将来可能会遇到边缘情况,并且无论如何都必须修改代码。

但是,如果您已经拥有泛型适合的多个场景,那么您现在可以从逻辑重用中受益,并且可以正确测试它们。

我看到其他人已经提供了代码答案,所以我就停在这里。

I think you shouldn't necessarily use generics to plan ahead for all possible future scenarios because you will likely run into edge cases in the future and have to modify the code regardless.

However if you already have multiple scenarios that a generic would fit to, then you can benefit from the logic reuse now and can test them all properly.

I see others have already provided code answers so I'll stop here.

苍景流年 2024-08-23 17:24:22

我认为这

DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue

是一个字符串。

您无法将字符串分配给 this.value,因为 this.value 的类型为 T 并且可以是任何类型,例如哪些字符串不可分配。

一种解决方案是删除泛型参数并使 value 成为字符串,然后提供不同的访问方式来解析 bool、float 或所需的任何内容。

public float GetFloatValue {
    get { return float.Parse(this.value); }
}

// etc

I assume that

DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue

is a string.

You can't assign a string to this.value because the type of this.value is T and could be anything, such as types to which strings are not assignable.

One solution is to remove the generic parameter and make value a string, and then provide different ways of accessing it which parse bools, floats, or whatever as required.

public float GetFloatValue {
    get { return float.Parse(this.value); }
}

// etc
木格 2024-08-23 17:24:22

看起来您正在尝试将字符串 (configsettings.SettingGroups[heading].Settings[key].RawValue) 分配给通用成员。您需要提供某种方法将字符串转换为 T 类型——通常是通过强制转换。例如:

this.value = (T)DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;

It looks like you're trying to assign a string (configsettings.SettingGroups[heading].Settings[key].RawValue) to the generic member. You'll need to provide some way to convert the string to type T -- usually through casting. For example:

this.value = (T)DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
最终幸福 2024-08-23 17:24:22

在这一行中:

this.value = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;

您将 T 类型的变量设置为字符串值。 RawValue 方法返回一个字符串。您需要将其显式转换为 T 类型。T

this.value = (T) (object) DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;

真的只是没有构造函数的值吗?如果您出于某种原因想避免这种情况,您也许可以明确说明并避免 object 转换。

In this line:

this.value = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;

you are setting your variable of type T to a string value. The RawValue method returns a string. You need to explicitly cast it to type T.

this.value = (T) (object) DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;

Is T really only going to be only values without constructors? You might be able to make that explicit and avoid the object casting, if you want to avoid that for some reason.

浅唱ヾ落雨殇 2024-08-23 17:24:22

请尝试 a 。

string strValue = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
this.value = (T)Convert.ChangeType(strValue, typeof(T), CultureInfo.InvariantCulture)

如果您将配置值存储为字符串并希望将其转换为正确的类型, 这只适用于大多数原始类型,如 Int32、Double 等。

Try a

string strValue = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
this.value = (T)Convert.ChangeType(strValue, typeof(T), CultureInfo.InvariantCulture)

if you have your configuration values stored as strings and want it converted to the right type. This only works for most of the primitive types like Int32, Double, etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文