相关疑难解决方法(0)

为什么核心类型仅部分实现接口?

Q1为什么.NET中的新类仅部分实现接口?

Q2我应该在我的代码中做同样的事情吗?

在这里问了这个问题,所以我想,好吧很久以前,你可以有不同的用法等等,现在这种实现只是出于一致性的原因而受到支持.但新课程也是如此.

int[] list = new int[] {};
IList iList = (IList)list;
ilist.Add(1); //exception here
Run Code Online (Sandbox Code Playgroud)

ICollection c = new ConcurrentQueue<int>();
var root = c.SyncRoot; //exception here
Run Code Online (Sandbox Code Playgroud)

UPDATE

我不担心为什么我得到例外,很明显.但我不明白为什么实现明确定义的合同,而不是所有成员(这可能导致令人不快的运行时异常)?

.net c# collections interface

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

静态和动态C#之间的互操作性差

这个问题在某种程度上是对相关帖子的说明,我相信下面的例子描述了问题的本质.

class Program
{
    public static IList<string> GetData(string arg)
    {
        return new string[] {"a", "b", "c"};
    }

    static void Main(string[] args)
    {
        var arg1 = "abc";
        var res1 = GetData(arg1);
        Console.WriteLine(res1.Count());

        dynamic arg2 = "abc";
        var res2 = GetData(arg2);
        try
        {
            Console.WriteLine(res2.Count());
        }
        catch (RuntimeBinderException)
        {
            Console.WriteLine("Exception when accessing Count method");
        }

        IEnumerable<string> res3 = res2;
        Console.WriteLine(res3.Count());
    }
}
Run Code Online (Sandbox Code Playgroud)

第二次调用GetData引发异常只是因为GetData接收到一个转换为动态的参数,这不是很糟糕吗?这个方法本身很好用这个参数:它将它视为一个字符串并返回正确的结果.但结果再次被转换为动态,突然结果数据无法根据其基础类型进行处理.除非它明确地转换回静态类型,正如我们在示例的最后几行中看到的那样.

我不明白为什么必须以这种方式实施.它打破了静态和动态类型之间的互操作性.一旦使用了动态,它会感染调用链的其余部分,从而可能导致像这样的问题.

更新.有些人指出Count()是一种扩展方法,有意义的是它不被识别.然后我将res2.Count()调用更改为res2.Count(从扩展方法更改为Ilist的属性),但程序在同一个地方引发了相同的异常!现在这很奇怪.

UPDATE2.flq指出了Eric Lippert关于这个主题的博客文章,我相信这篇文章给出了为什么以这种方式实现的充分理由:http: //blogs.msdn.com/b/ericlippert/archive/2012/10/22/a -method基团的-one.aspx

c# static dynamic c#-4.0

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

基类/抽象类中的C#最佳部分接口实现

.net不允许在基类中实现部分接口.作为缓解措施,我已经提出了3种替代解决方案.请帮我决定哪些在重构,编译/运行时错误,可读性方面更具普遍性.但首先是几条评论.

  • 当然,您可以始终将对象转换为IFoo并在没有任何编译器警告的情况下调用任何方法.但这不符合逻辑,你不会这样做.这种结构不会因重构而发生.
  • 我想要最大限度的分离 直接类契约(公共方法和属性)应该与接口实现分开.我经常使用接口来分隔对象的交互.

我的比较:

  1. BaseClass1/MyClass1的:
    • con:必须在BaseClass1中为每个未实现的IFoo方法创建虚拟抽象.
    • con:附加方法换行 - 在运行时对生产力的影响很小.
  2. BaseClass2/MyClass2:
    • con:如果在MyClass2中没有实现Method2,则没有编译器警告.而是运行时异常.单元测试覆盖率较差的重构可能会破坏代码的稳定性.
    • con:必须添加额外的过时构造以防止来自子类的直接方法调用.
    • con:Method2对于BaseClass1是公共的,因此它现在是类合同的一部分.必须使用"过时"构造来防止直接调用,而不是通过IFoo.
  3. BaseClass3/MyClass3:
    • 亲:(与#2相比).更具可读性.您看到MyClass2.Method2是IFoo实现,而不仅仅是一些覆盖方法.
public interface IFoo
{
    void Method1();
    void Method2();
}
Run Code Online (Sandbox Code Playgroud)
public abstract class BaseClass1 : IFoo
{
    void IFoo.Method1()
    { 
        //some implementation
    }

    void IFoo.Method2()
    {
        IFooMethod2();
    }

    protected abstract void IFooMethod2();
}

public class MyClass1 : BaseClass1
{
    [Obsolete("Prohibited direct call from child classes. only inteface implementation")]
    protected override void IFooMethod2()
    {
        //some implementation
    }
}
Run Code Online (Sandbox Code Playgroud)
public abstract class BaseClass2 : IFoo
{
    void …
Run Code Online (Sandbox Code Playgroud)

c# refactoring abstract-class interface

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

如何将数组转换为BindingList

将数组转换为BindingList最简单快捷的方法是什么?

c# bindinglist type-conversion

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

Enumerable.Empty to List

例如,如果我有这个方法:

IEnumerable<int> GetRandomNumbers()
{
    // {Codes that generate numbers as List<int>}
    if(generationFails == true)
    {
        return Enumberable.Empty<int>(); // I do this to signal that we have an error
    }
    return numbers;
}
Run Code Online (Sandbox Code Playgroud)

在调用方法中我做:

IEnumerable<int> AddNumber(int number)
{
    var random = GetRandomNumbers();
    var randomList = random  as IList<int> ?? random.ToList(); // Run ToList only if needed
    randomList.Add(number); 
    return randomList;
}
Run Code Online (Sandbox Code Playgroud)

当生成失败时,我得到一个异常"[NotSupportedException:Collection是固定大小的.]".

这是因为Enumerable empty是一个IList,因此.ToList()没有运行,然后我尝试添加到一个固定的Enumberable.Empty.我错误地认为这是一个糟糕的设计,一个继承IList的对象(其中定义了Add)应该支持Add?

我被迫做var randomList = random.ToList()或停止使用Enumberable.Empty?有更好的方法吗?

更新: 我想在我的例子中我不清楚.我希望吞下(或记录)错误,但允许操作继续而不会崩溃.我的评论"我这样做是为了表明我们有错误"是为了告诉其他开发人员阅读代码,这是一种异常行为.

蒂姆所关联的问题的答案就是我所得到的.似乎我们只是没有用于常量集合的接口,因此IList被使用.

c#

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

int []是否有资格作为IList <T>?

在stackoverflow的另一个问题中,有人建议为数组编写扩展方法,但this IList<T>在扩展方法中使用了接口.我评论它应该是一个阵列,但他拒绝了.我测试了它,当然,他是对的...... :)

扩展方法:

public static void Fill<T>(this IList<T> array, T value)
{
    for(var i = 0; i < array.Count; i++) 
    {
        array[i] = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

[Test] 
public void Stackoverflow()
{
    int[] arr = new int[] { 1,2,3,4};
    arr.Fill(2);
    Assert.AreEqual(2, arr[0]);
    Assert.AreEqual(2, arr[1]);
    Assert.AreEqual(2, arr[2]);
    Assert.AreEqual(2, arr[3]);
}
Run Code Online (Sandbox Code Playgroud)

一个array不是IList<T>.为什么这甚至编译?通过?!

c#

0
推荐指数
2
解决办法
274
查看次数

将List <string>或string []数组传递给C#方法

我的C#类中有以下方法.

对于名为'collections'的参数,我希望能够灵活地传递List或string []数组.我知道我可以简单地将参数类型设置为对象类型,但是还有其他更高效的类型可以用来做这个吗?

public string ProcessDoc(List<string> collections, string userName)
{
  //code goes here
   string result = null;
   ...
   ...
   return result;
}
Run Code Online (Sandbox Code Playgroud)

c# collections parameter-passing

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