Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在库api中使用字符串与类型_C#_.net_Api_Design Patterns - Fatal编程技术网

C# 在库api中使用字符串与类型

C# 在库api中使用字符串与类型,c#,.net,api,design-patterns,C#,.net,Api,Design Patterns,我正在设计一个我希望其他人使用的库,其中系统中的“东西”可以在运行时动态地分配给它们任意属性。在我的例子中,属性是一个类,它有一个委托函数,在给定一些输入(而不是C语言属性)的情况下返回一个浮点值。每个“东西”都有一些获取和设置这些属性的方法。在内部,每件事都将属性存储在字典中,但我不想向api使用者公开对该字典的直接访问,因为set/get方法还将执行诸如发出事件之类的操作 我正在和自己讨论如何访问这些属性。我的第一个想法是保持简单并使用字符串,因此get方法可能是thing.GetAttri

我正在设计一个我希望其他人使用的库,其中系统中的“东西”可以在运行时动态地分配给它们任意属性。在我的例子中,
属性
是一个类,它有一个委托函数,在给定一些输入(而不是C语言属性)的情况下返回一个浮点值。每个“东西”都有一些获取和设置这些属性的方法。在内部,每件事都将属性存储在
字典中
,但我不想向api使用者公开对该字典的直接访问,因为set/get方法还将执行诸如发出事件之类的操作

我正在和自己讨论如何访问这些属性。我的第一个想法是保持简单并使用字符串,因此get方法可能是
thing.GetAttribute(“Height”)
。但我不喜欢这样做有几个原因:1)字符串名很容易拼写错误。2.)这不是类型安全的,一次只能有一个给定“类型”的属性。所以我的下一个想法是使用泛型来消除松散字符串的危险。v2 api可能如下所示:
thing.GetAttribute()

这样做的缺点显然是需要为每个属性类型声明类,但属性实现之间几乎没有任何区别,因此要求为每个需要添加的属性声明类似乎很烦人。(尽管使用UI生成代码在这方面非常重要)。如果这些类都是预先声明的,我更喜欢这里的通用解决方案

一个更完整的示例:

var flower = new Item();
flower.SetAttribute<Petals>(4f);
float petalCount= flower.GetAttribute<Petals>(); //4
flower.GetAttribute<Gears>(); //0, flower doesnt have a Gears attribute

忽略以下事实:这是一个相当精心设计的示例,并且没有完全解释这个Get/Set api的系统和原因,这是一个性能良好的api设计?有没有我在这里没有想到的另一种模式可以工作?

由于您声明的类并不真正对应于属性类型(它们都是浮动),因此泛型版本实际上是一个奇怪的api。您最好使用字符串版本,但将所有字符串作为常量字段放在类中的某个位置,这样它们就不是神奇的字符串

你也可以用字典


您可能还需要查看ExpandooObject和dynamic关键字。

我将使用从dictionary类派生的类:

public class Item : Dictionary<Type. float>
{
    public float this[Type index]
    {
        get
        {
            if (ContainsKey(index)
                return base[index];
            return 0f;
        }
        set
        {
            Add(index, value);
        }
    }
}

泛型的好处是它们增加了编译时类型的安全性。糟糕的是,类型需要在编译时就知道,而在很多情况下,类型是未知的。我是否希望读取用户输入(可能来自xml文件)并动态创建具有某些属性的项?如果是这样的话,仿制药会让这种情况变得痛苦。我可以动态定义新属性吗?问题是属性及其定义的动态性如何。在运行时生成属性的好处是。我不认为我需要这样做,但删除选项似乎是个坏主意。我不知道动态关键字,这很酷!我想你说的奇怪是对的,我将使用常量字符串解决方案,谢谢。
public class Item : Dictionary<Type. float>
{
    public float this[Type index]
    {
        get
        {
            if (ContainsKey(index)
                return base[index];
            return 0f;
        }
        set
        {
            Add(index, value);
        }
    }
}
var flower = new Item();
flower[typeof(Petals)] = 4f;
float petalCount = flower[typeof(Petals)]; //4
flower[typeof(Gears)]; //0, flower doesnt have a Gears attribute