小编Ste*_*ven的帖子

是否可以定义实现多个接口的任何类型的列表?

考虑以下类层次结构:

public interface X { void Foo(); }

public interface Y { void Bar(); }

public class A : X, Y
{
    public void Foo() {}
    public void Bar() {}
}

public class B : X, Y
{
    public void Foo() {}
    public void Bar() {}
}
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以定义一个列表(或任何通用类型),它可以包含A's和B's',同时允许我将所述列表的内容视为两者XY?也就是说,这将允许我写下这样的内容:

var list = ???
list.Add(new A());
list.Add(new B());
list.First().Foo();
list.Last().Bar();
Run Code Online (Sandbox Code Playgroud)

编辑

只是为了澄清,我目前正在处理的类型是ObservableCollection<T>(A)和ReadOnlyObservableCollection<T>(B),我感兴趣的接口是IList<T>(X)和 …

c# generics

15
推荐指数
2
解决办法
2052
查看次数

有效实施flyweight模式

背景

我们的应用程序中最常用的数据结构之一是自定义Point结构.最近我们遇到了内存问题,主要是由于这个结构的实例数过多引起的.

其中许多实例包含相同的数据.共享单个实例将显着有助于减少内存使用.但是,由于我们使用的是结构,因此无法共享实例.也不可能将其更改为类,因为结构语义很重要.

我们的解决方法是使结构包含对支持类的单个引用,该引用类包含实际数据.这些flyweight数据类存储在工厂中并从工厂中检索,以确保不存在重复项.

缩小版本的代码看起来像这样:

public struct PointD
{
    //Factory
    private static class PointDatabase
    {
        private static readonly Dictionary<PointData, PointData> _data = new Dictionary<PointData, PointData>();

        public static PointData Get(double x, double y)
        {
            var key = new PointData(x, y);
            if (!_data.ContainsKey(key))
                _data.Add(key, key);

            return _data[key];
        }
    }

    //Flyweight data
    private class PointData
    {
        private double pX;
        private double pY;

        public PointData(double x, double y)
        {
            pX = x;
            pY = y;
        }

        public double X
        {
            get { return pX; …
Run Code Online (Sandbox Code Playgroud)

c# design-patterns

6
推荐指数
1
解决办法
820
查看次数

多次实现协变接口:这种行为是否正确定义?

给出以下协变通用接口

public interface IContainer<out T>
{
    T Value { get; }
}
Run Code Online (Sandbox Code Playgroud)

我们可以为多个泛型类型创建一个多次实现此接口的类.在我感兴趣的场景中,这些泛型类型共享一个共同的基类型.

public interface IPrint
{
    void Print();
}
public class PrintA : IPrint
{
    public void Print()
    {
        Console.WriteLine("A");
    }
}
public class PrintB : IPrint
{
    public void Print()
    {
        Console.WriteLine("B");
    }
}

public class SuperContainer : IContainer<PrintA>, IContainer<PrintB>
{
    PrintA IContainer<PrintA>.Value => new PrintA();
    PrintB IContainer<PrintB>.Value => new PrintB();
}
Run Code Online (Sandbox Code Playgroud)

现在通过类型引用使用此类时,事情变得有趣IContainer<IPrint>.

public static void Main(string[] args)
{
    IContainer<IPrint> container = new SuperContainer();
    container.Value.Print();
} …
Run Code Online (Sandbox Code Playgroud)

c# covariance

6
推荐指数
1
解决办法
102
查看次数

为什么 INotifyCollectionChanged 不扩展 IList?

我曾多次遇到过这样的情况:我想通过INotifyCollectionChanged界面观察一个集合,但又希望能够访问该集合的任何元素。该INotifyCollectionChanged接口不提供任何访问元素的方法,除了那些涉及更改事件的元素(通常包含在 中NotifyCollectionChangedEventArgs)。

现在这是我的想法:

  1. 我们知道无论实现什么INotifyCollectionChanged都是一个集合(d'uh)。
  2. 由于NotifyPropertyChangedEventArgs包含索引指示更改的位置,我们知道元素可以通过索引访问。

可以通过索引访问的集合是一个列表,因此要求任何INotifyCollectionChanged实现者也实现IList. 这可以通过让INotifyCollectionChanged扩展轻松完成IList

有谁知道为什么不是这样?

.net c# collections

5
推荐指数
1
解决办法
488
查看次数

为什么type.Assembly.GetType(type.Name)返回null?

Type type = typeof(MyType);
Type copy = type.Assembly.GetType(type.Name);
Run Code Online (Sandbox Code Playgroud)

对我来说,上面的代码最终应该copy是对同一个对象的另一个引用,这似乎微不足道type.但是,我一直在努力copy == null.如果我使用过载Assembly.GetType(type.Name, true)它会抛出一个TypeLoadException.

这种类型的组件找不到这种类型是不是很奇怪?它肯定在那里!以下是真实的:

type.Assembly.GetTypes()[0] == type;
type.Assembly.GetExportedTypes()[0] == type;
Run Code Online (Sandbox Code Playgroud)

如果这是预期的行为,有人可以解释为什么这样吗?

如果不是,有人能指出任何可能导致这种情况发生的事情吗?


超级简单的演示:

public class Program
{
    static void Main(string[] args)
    {
        var type = typeof(Program);
        Console.WriteLine(type.Assembly.GetExportedTypes()[0] == type); // True
        Console.WriteLine(type.Assembly.GetType(type.Name, true)); // exception
    }
}
Run Code Online (Sandbox Code Playgroud)

c#

1
推荐指数
1
解决办法
694
查看次数

标签 统计

c# ×5

.net ×1

collections ×1

covariance ×1

design-patterns ×1

generics ×1