gpt4 book ai didi

c# - 使用字典和泛型创建嵌套的 JSON 可序列化对象结构时 .NET 中的 C# 协方差问题

转载 作者:行者123 更新时间:2023-11-30 21:36:31 25 4
gpt4 key购买 nike

我在使用字典和泛型在 C# 中创建嵌套对象结构时遇到了一些问题(我使用的是 Visual Studio、.NET Framework 4.6+)

主要问题是 C# 字典中缺少协变。

我必须在 C# 中创建这个简单的(JSON 可序列化/反序列化)对象结构。我试着用动物来解释......

public class AnimalCatalog
{
public Dictionary<string, Animal> AnimalsDict { get; set; } // key is the species name
}

public class Animal // base class
{
public string Species { get; set; } // univocal
public bool CanFly { get; set; }
public Dictionary<string, GenericPaw> PawsDict { get; set; } // each animal has a different type and a different number of paws
}

public class GenericPaw // base class
{
public int FingerNumber { get; set; } // number of finger in each paw
}

public class Cat : Animal // derived class
{
public void meow() // only cats says 'meow'
{...}
}

public class CatPaw : GenericPaw // derived class
{
public void scratch() // cats paws could scratch something :) but not all the animals paws could
{...}
}

我使用 C# 泛型实现了这个结构,因为 Cat 有一个 CatPaws 字典,而不是泛型 Paws :P。这是我的建议。

public class AnimalCatalog<T,V> where T : Animal<V> where V : GenericPaw 
{
public Dictionary<string, T> AnimalsDict { get; set; } = new Dictionary<string, T>(); // key is the species name
}

public class Animal<T> where T : GenericPaw // base class
{
public string Species { get; set; } // univocal
public bool CanFly { get; set; }
public Dictionary<string, T> PawsDict { get; set; } // each animal has a different type and a different number of paws
}

public class GenericPaw // base class
{
public string PawName { get; set; } // univocal
public int FingerNumber { get; set; } // number of finger in each paw
}

public class Cat<T> : Animal<T> where T : CatPaw // derived class
{
public void meow() // only cats says 'meow'
{...}
}

public class CatPaw : GenericPaw // derived class
{
public void scratch() // cats paws could scratch something :) but not all the animals paws could
{...}
}

让我们使用创建的类<​​/p>

Cat<CatPaw> Kitty = new Cat<CatPaw>();   // create a cat
CatPaw KittyFirstPaw = new CatPaw(); // create the 1st cat's paw
Kitty.PawsDict.Add(KittyFirstPaw.PawName, KittyFirstPaw); // add the paw to the dict
AnimalCatalog<Animal<GenericPaw>,GenericPaw> ZooCatalog = new AnimalCatalog<Animal<GenericPaw>,GenericPaw>(); // create a catalog of animals
Animal<GenericPaw> GenericAnimal = Kitty; <-- doens't compile (can't convert derived to base class)
AnimalCatalog.AnimalsDict.Add(GenericAnimal.Species, GenericAnimal);

我还尝试使用接口(interface)而不是基类,使用 out 关键字将 T 指定为协变类型,但它不起作用,因为我不能在 dict 中使用协变类型...

非常感谢任何帮助:)斯特凡诺

最佳答案

您无法转换 Cat<CatPaw>Animal<GenericPow> , 因为这样你就可以添加不同类型的 GenericPaw放入它的字典(例如 DogPaw ),猫不会喜欢的。

这只是一个问题,因为您可以在字典中插入新值,所以看起来可以通过使用 IReadOnlyDictionary 来解决。 ,但不幸的是,由于 this question 中描述的技术问题,该变量也不是协变的。 .

附带说明一下,为什么要 Cat 是有原因的吗?也是通用的?

public class Cat<T> : Animal<T> where T : CatPaw

如果你想创建一只只能拥有来自 CatPaw 的某些特定爪子的猫,这将很有用。 .如果没有,这可能会变成:

public class Cat : Animal<CatPaw>

AnimalCatalog似乎也不必要地复杂。如果您只需要 Animal 的动物目录,它可以简化为只有一个通用参数:

public class AnimalCatalog<TPaw> where TPaw : GenericPaw
{
public Dictionary<string, Animal<TPaw>> AnimalsDict { get; set; }
}

如果你只需要一个 AnimalCatalog<GenericPaw> ,您也可以去掉一个参数。但是这个目录仍然不是很有用,因为你不能转换 Animal<CatPaw>。至 Animal<GenericPaw> .

要解决这个问题,您可以创建 IAnimal<out TPaw> 的协变接口(interface)具有 Animal 的所有属性但是您可以将爪子公开为 IEnumerable<TPaw> Paws 而不是字典如果你需要字典查找,一个方法:TPaw GetPaw(string pawName) .这些将使用字典来实现。然后可以转换 Cat (这是一个 Animal<CatPaw> 因此也是 IAnimal<CatPaw> )到 IAnimal<GenericPaw> .您的动物目录将包含 IAnimal<GenericPaw> .

关于c# - 使用字典和泛型创建嵌套的 JSON 可序列化对象结构时 .NET 中的 C# 协方差问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48060913/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com