65.9K
CodeProject 正在变化。 阅读更多。
Home

“var 关键字用于 JavaScript” - 关于使用 var 关键字和其他编码指南

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.71/5 (5投票s)

2010 年 3 月 31 日

CPOL

3分钟阅读

viewsIcon

16255

“var 关键字用于 JavaScript” - 关于使用 var 关键字和其他编码指南

引言

今天我正在阅读一篇 CodeProject 上的文章,我对某些人评价文章和发表评论的方式感到非常震惊...

这是一篇关于有人实现了一个简单的服务定位器的文章,其中包含以下代码示例

using System; 
using CuttingEdge.ServiceLocation; 
using Microsoft.Practices.ServiceLocation; 

public class Global : System.Web.HttpApplication 
{
  protected void Application_Start(object sender, EventArgs e) 
  { 
     // 1. Create a new Simple Service Locator container 
     var container = new SimpleServiceLocator(); 

     // 2. Configure the container 

     // Register a delegate that will create a new 
     // instance on each call to GetInstance. 
     container.Register<ISamurai(() => 
     { 
        var weapon = ServiceLocator.Current .GetInstance(); 
        return new Samurai(weapon); 
      }); 

      // Register a single object instance that always 
      // be returned (must be thread-safe). 
      container.RegisterSingle(new Katana()); 

      // 3. Register the container to the Common Locator 
      ServiceLocator.SetLocatorProvider(() => container); 
    } 
}

这对我来说似乎很明显。 由于我注意到一篇 标题为“我的 2 分评价”的评论,我很好奇为什么这篇文章会得到这么低的分数(5 分中的 2 分)。 我查看了评论,感到非常震惊

请注意:关键字“var”应该与匿名类型一起使用。 您不应该将其用于其他任何事情。 否则请开始编写 java script

谁在乎呢?

实际上,我在乎。

由于我无法抗拒,我发表了以下评论

嗯……关于这个问题已经有很多争论,但总的来说,这不应该构成问题,因为它在开始时非常清楚它的意图;

var sl = new SimpleServiceLocator();

并不比这更明显

SimpleServiceLocator sl = new SimpleServiceLocator();

事实上,里面的信息是相同的,但第二个更冗长,所以每个头脑清醒的人都会选择第一个替代方案。
如果你使用一个没有在函数名称中直接暴露返回类型的函数,这可能会有所不同; 比如

var x = SomeFunction(y,z); 

这被大多数人认为是不好的做法。

这个不是

var myservice = sl.Resolve<IMyService>();

因为初始化包含足够明显的信息来指示 var 的类型。

所以,如果这是你只给 2 分的唯一原因(作者显然在这篇文章上投入了相当多的时间),那么你可能需要开始自己编写一些 JavaScript。

在推特上谈论这件事后,我与 @JacoPretorious 进行了一次有趣的对话,他说他到处都使用 var ,但更关注变量名。

虽然我理解他的意思,但 IMHO 变量名不应该推断类型,只应该在必要时推断内容的含义。

我个人认为使用单个字母作为变量名没有错,只要意图明显即可。 这是一个完全有效的例子,IMO

public bool InvalidateCustomer(int CustomerId)
{
  var c = sRepo.GetById<Customer>(CustomerId);
  if ( c.Orders.Where(o=>o.PaymentReceivedOn==null).Any()) 
    return false;
  c.Valid=false;
  sRepo.SaveOrUpdate(c);
  sUOW.Commit();
  return true;
}

这个 IMO 不成立

public class MyProcessQueue
{
  public void ProcessQueue()
  { 
    for(;;)
    {
       var p = Queue.Next();
       if (p==null) 
         break;
       sProcessor.Process(p);
    }
  }
}

由于你无法从 Queue 推断类型,你应该明确类型

public class MyProcessQueue
{ 
  public void ProcessQueue()
  {
    for(;;)
    {
       Order o = Queue.Next();
       if (o==null) 
         break;
       sProcessor.Process(o);
    }
  }
}

如果 MyProcessQueue 是泛型类,这将改变

public class MyProcessQueue<T> where T:ISomeInterface
{
  public void ProcessQueue()
  { 
    for(;;)
    {
       var p = Queue.Next();
       if (p==null) 
         break;
       sService.Process(p);
    }
  }
}

在这种情况下,我认为你拥有足够的信息来知道类型应该与泛型类有关。 为变量使用更明确的名称并没有为我添加很多信息; 我认为以下(夸张的)例子并不比之前的例子更明显; 事实上,这需要更多的时间来获取意图,因为你的大脑需要处理更多信息(还要注意注释,它们没有为我提供任何额外信息)

public class MyProcessQueue<T>
  where T:ISomeInterface
{  
  // Process all jobs in the queue, until there is nothing left  
  public void ProcessAllISomeInterfacesInTheQueue()
  { 
    // loop forever
    for(;;)
    {
       // get the next instance to process from the queue; 
       // if it returns null there are no more processes left on the queue
       ISomeInterface TheNextISomeInterfaceInstanceToProcess = Queue.Next(); 
       if (TheNextISomeInterfaceInstanceToProcess==null)
       {
          //exit the infinite loop
         break;
        }
       // process it
       sServiceThat ProcessesSomeInterfaceInstance.Process
		(TheNextISomeInterfaceInstanceToProcess);
    }
   // return
  }
}

这里的信息太多了,这些信息都可以很容易地从代码中推导出来,如果你更改代码并忘记注释,这实际上可能会适得其反:造成混淆。

结论

虽然这完全取决于你的偏好,并且高度依赖于你的观点和背景,但我确实认为我个人使用的方法是更好的方法之一。 它们提供了你可能需要的所有信息量,代码量最少。

如果你有不同的意见,请不要犹豫让我知道...

© . All rights reserved.