小编Yac*_*sad的帖子

在Visual Studio中,有没有办法按用法对私有方法进行排序?

在Visual Studio中,有或没有扩展,有没有办法根据用法的顺序(它们在调用堆栈中的位置)自动对类中的私有方法进行排序?

例如,考虑以下类:

public class MyClass
{
    public void MyMethod()
    {
        TestC();
    }

    private void TestA()
    {
        TestB();
    }

    private void TestB()
    {
        Console.WriteLine("Hello");
    }

    private void TestC()
    {
        TestA();
    }
}
Run Code Online (Sandbox Code Playgroud)

这个类中的公共方法是MyMethod,它调用TestC哪个调用TestA哪个调用TestB.我想(自动)按此顺序对这些方法进行排序,以便类看起来像这样:

public class MyClass
{
    public void MyMethod()
    {
        TestC();
    }

    private void TestC()
    {
        TestA();
    }

    private void TestA()
    {
        TestB();
    }

    private void TestB()
    {
        Console.WriteLine("Hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要能够选择一个类,请求这样的方法排序,并让方法自动排序.即,我不想手动对这些方法进行排序.

我知道有一些细微差别.例如,可能存在从两个方法调用的私有方法,这两个方法在调用堆栈中处于两个不同的级别.我想在这种情况下考虑与公共方法的最小(调用堆栈)距离是有意义的.

更新:

这种以这种方式对方法进行分类的想法来自Robert C. Martin的清洁代码书.在第3章中,定义了Stepdown规则,该规则讨论了在低级函数之前出现更高级别的函数.

在google上快速搜索stepdown规则,我发现了一个netbeans插件:http://plugins.netbeans.org/plugin/58863/stepdownruleplugin …

c# refactoring visual-studio

26
推荐指数
3
解决办法
1682
查看次数

为什么下面的代码输出 System.Int32 而不是 System.String?

为什么下面的代码输出System.Int32而不是System.String

public class A<T>
{
    public class B : A<int>
    {
        public void M() { System.Console.WriteLine(typeof(T)); }
        public class C : B { }
    }
}

public class P
{
    public static void Main() { (new A<string>.B.C()).M(); }
}
Run Code Online (Sandbox Code Playgroud)

我得到了这个代码表:https : //www.dotnetcurry.com/csharp/1292/eric-lippert-interview

c# type-systems

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

如何从任何两个BlockingCollections中获取优先于第一个集合的项目?

我有两个BlockingCollection<T>对象,collection1collection2.我想要使​​用这些集合中的项目优先考虑项目collection1.也就是说,如果两个集合都有项目,我想先从中获取项目collection1.如果他们都没有物品,我想等待物品可用.

我有以下代码:

public static T Take<T>(
    BlockingCollection<T> collection1,
    BlockingCollection<T> collection2) where T:class
{
    if (collection1.TryTake(out var item1))
    {
        return item1;
    }

    T item2;

    try
    {
        BlockingCollection<T>.TakeFromAny(
            new[] { collection1, collection2 },
            out item2);
    }
    catch (ArgumentException)
    {
        return null;
    }

    return item2;
}
Run Code Online (Sandbox Code Playgroud)

在两个集合上调用此代码nullCompleteAdding,它们都会返回,并且它们都是空的.

我对此代码的主要问题是该TakeFromAny方法的文档指定TakeFromAny将在"集合"上调用ArgumentExceptionif CompleteAdding:

ArgumentException的

collections参数是一个0长度数组或包含null元素,或者已在集合上调用CompleteAdding().

如果CompleteAdding在任何集合上调用它会抛出吗?或两个集合?

如果CompleteAdding被调用并且集合仍然有一些项目,它会抛出吗?

我需要一种可靠的方法来做到这一点.

在这段代码中,我试图从collection1第一个开始,因为TakeFromAny …

c# producer-consumer

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

如何在.NET中使用类型等效功能?

我试图了解.NET的类型等效功能。我在一个解决方案中创建了三个项目,两个库和一个控制台应用程序。

在库中,我定义了以下类型:

ClassLibrary1:

namespace ClassLibrary1
{
    [TypeIdentifier("scope1", "identifier1")]
    public interface IInterface1
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

ClassLibrary2:

namespace ClassLibrary2
{
    [TypeIdentifier("scope1", "identifier1")]
    public interface IInterface1
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

我根据此处的文档进行了此操作:https : //docs.microsoft.com/zh-cn/dotnet/framework/interop/type-equivalence-and-embedded-interop-types

并在控制台应用程序中:

static void Main(string[] args)
{
    ClassLibrary1.IInterface1 variable1 = null;

    ClassLibrary2.IInterface1 variable2 = null;

    variable1 = variable2;
}
Run Code Online (Sandbox Code Playgroud)

我收到这些编译错误:

错误CS0234类型或名称空间名称'IInterface1'在名称空间'ClassLibrary2'中不存在(您是否缺少程序集引用?)

错误CS0234类型或名称空间名称'IInterface1'在名称空间'ClassLibrary1'中不存在(您是否缺少程序集引用?)

如果TypeIdentifier从接口定义中删除属性,这两个错误就会消失,但是编译器当然不会允许变量分配,因为它们是不同的类型。

我的问题是,如果用TypeIdentifier属性注释类型,为什么类型似乎消失了?以及如何在.NET中使用类型等效?

更新:我试图将库引用为DLL而不是项目,并且得到相同的结果。

更新:

我能够在.NET Framework和.NET Core 3中使类型等效工作。

可以在这里找到源代码:https : //github.com/ymassad/TypeEquivalenceExample

因此,我目前的理解是,该TypeIdentifier属性不应直接由开发人员使用。

当项目A引用项目B时,它可以指定它想要“嵌入互操作类型”。有一些条件可以使它起作用,但结果是A中使用的B中的类型将在编译A时在生成的Assembly中复制。这些类型将由编译器使用此属性进行注释。似乎该功能是专门为使.NET应用程序使用COM类型而无需部署称为“主互操作程序集”的程序集而设计的。该PIA程序集包含与某个基于COM的库进行通话所需的所有元数据。如果应用程序/库仅需要该库中的几种类型,则可以选择仅将这些类型嵌入其内部。这里需要类型等效,以便嵌入在不同程序集中的不同类型可以互换使用。

我找不到任何文档来解释为什么以我在此问题中描述的直接方式使用此功能无法正常工作。如果有人可以对此有所阐明,我将不胜感激。有没有办法使这个问题描述的方式起作用?

.net c# clr

5
推荐指数
0
解决办法
187
查看次数

如何使用通用参数为任何方法构建表达式调用

我只是尝试使用Linq.Expression创建如下表达式:

Expression<Func<Organization, bool>> expression = @org => 
    @org.OrganizationFields.Any(a =>
        a.CustomField.Name == field.Name &&
        values.Contains(a.Value));
Run Code Online (Sandbox Code Playgroud)

在上面的这个例子中,我有一个名为Organization的实体,它有一个名为OrganizationsFields的属性作为IEnumerable,我想找到任何与Any参数表达式匹配的事件.

我只是使用下面的代码动态生成表达式:

string[] values = filter.GetValuesOrDefault();

ParameterExpression parameter = Expression.Parameter(typeof(T), "org");
Expression organizationFields = Expression.Property(parameter, "OrganizationFields");

MethodInfo any = typeof(Enumerable)
   .GetMethods()
   .FirstOrDefault(a => a.Name == "Any" && a.GetParameters().Count() == 2)
   .MakeGenericMethod(typeof(OrganizationField));

Func<OrganizationField, bool> functionExpression = a =>
    a.CustomField.Name == filter.Name && values.Contains(a.Value);

Expression functionParam = Expression.Constant(
    functionExpression,
    typeof(Func<OrganizationField, bool>));

Expression call = Expression.Call(organizationFields, any, functionParam);

return Expression.Lambda<Func<T, bool>>(call, parameter);
Run Code Online (Sandbox Code Playgroud)

当我调用方法Expression.Call它抛出一个ArgumentExeption时会出现问题

谁能帮我?

问候

c# linq reflection expression

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

是否可以创建条件语句数组?

我正在使用excel调用进行条件语句,我想知道是否有办法让我的程序检查它循环的条件数组,而不是一堆"或"语句.我的代码如下:

while(
    activesheet.Range["A" + n].Text != "sting 1" 
    || activesheet.Range["A" + n].Text != "string 2"
    || activesheet.Range["A" + n].Text != "string 3"...)
{
    n++;
}
Run Code Online (Sandbox Code Playgroud)

是否可以有一系列条件,我的excel文件的每一行都可以强制通过?我似乎无法弄清楚,还没有找到任何答案或例子.我想我可以使用'foreach'电话,但我不确定如何为我的目的实现它.谢谢.

c# excel

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

如何使用WhenCustomCommandReceived设置Topshelf?

我正在使用Topshelf创建一个Windows服务(ServiceClass),我正在考虑使用WhenCustomCommandReceived发送自定义命令.

HostFactory.Run(x =>
{
    x.EnablePauseAndContinue();
    x.Service<ServiceClass>(s =>
    {
        s.ConstructUsing(name => new ServiceClass(path));
        s.WhenStarted(tc => tc.Start());
        s.WhenStopped(tc => tc.Stop());
        s.WhenPaused(tc => tc.Pause());
        s.WhenContinued(tc => tc.Resume());
        s.WhenCustomCommandReceived(tc => tc.ExecuteCustomCommand());
    });
    x.RunAsLocalSystem();
    x.SetDescription("Service Name");
    x.SetDisplayName("Service Name");
    x.SetServiceName("ServiceName");
    x.StartAutomatically();
});
Run Code Online (Sandbox Code Playgroud)

但是,我在WhenCustomCommandReceived行上收到错误:

委托'Action <ServiceClass,HostControl,int>'不带1个参数

签名是

ServiceConfigurator<ServiceClass>.WhenCustomCommandReceived(Action<ServiceClass, HostControl, int> customCommandReceived)
Run Code Online (Sandbox Code Playgroud)

我已经有了在我的ServiceClass中启动,停止,暂停的方法:public void Start()等.有人能指出我如何设置Action的正确方向吗?谢谢!

c# topshelf

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