2013-08-21 12 views
3

此示例:如何定义一个类型T必须有一个字段“ID”

public static void createDictionary<T>(IEnumerable<T> myRecords) 
      where T: T.ID // Wont Compile 
     { 
      IDictionary<int, T> dicionario = myRecords.ToDictionary(r => r.ID); 


      foreach (var item in dicionario) 
      { 
       Console.WriteLine("Key = {0}",item.Key); 

       Type thisType = item.Value.GetType(); 

       StringBuilder sb = new StringBuilder(); 

       foreach (var itemField in thisType.GetProperties()) 
       { 
        sb.AppendLine(string.Format("{0} = {1}", itemField.Name, itemField.GetValue(item.Value, null))); 
       } 

       Console.WriteLine(sb); 
      } 

     } 

我怎么能强迫作为参数传递的类型所称的“ID”字段?

回答

9

你可以创建一个接口:

public interface IWithID 
{ 
    // For your method the set(ter) isn't necessary 
    // public int ID { get; set; } 
    public int ID { get; } 
} 

public static void createDictionary<T>(IEnumerable<T> myRecords) 
     where T: IWithID 

你需要使用一个属性,而不是一个场以这种方式。

或明显你可以使用一个基本类型...

public abstract class WithID 
{ 
    // public int ID; // non readonly 
    public readonly int ID; // can even be a field 
} 

public static void createDictionary<T>(IEnumerable<T> myRecords) 
     where T: WithID 

另一种解决方案是通过一个委托:

public static void createDictionary<T>(IEnumerable<T> myRecords, 
             Func<T, int> getID) 

然后使用GetID来获取ID,如myRecords.ToDictionary(getID)

+0

我建议物业ID的 “接口”使属性为只读而不是读/写;我很少想要一个ID属性是可写的。 –

+0

@JonSkeet我正在考虑EF POCO课 – xanatos

+0

我试图逃避宣布一个新的界面......我认为有一个解决方案的字段名称......但是,谢谢 –

5

从定义为IDinterface继承。

public interface IIDInterface { 
    int ID { get; set; } 
} 


public static void createDictionary<T>(IEnumerable<T> myRecords) 
      where T: IIDInterface 
+0

IIdentifiable 带T领域的标识符{get; set;}是一个更好的设计,在我看来。 – Krythic

0

where语法旨在表明该类基于其他一些类。所以,你需要一个基类:

public abstract class IDBaseClass 
{ 
    public int ID { get; set; } 
} 

来然后改变它的东西是这样的:

where T : IDBaseClass 

然后,您使用那里的类型只需要基础,阶级。现在,如果因为你的类型已经立足的东西你不能建立一个抽象类,你可以用一个接口:

public interface IIDInterface 
{ 
    int ID { get; set; } 
} 

,你可以改变where语法是:

where T : IIDInterface 

所以那么使用这个泛型类的类型只需要实现该接口。

相关问题