2009-11-14 40 views
8

我想创建一个简单的通用功能C#:如何使用泛型方法与“走出去”可变

void Assign<T>(out T result) 
{ 
    Type type = typeof(T); 
    if (type.Name == "String") 
    { 
    // result = "hello"; 
    } 
    else if (type.Name == "Int32") 
    { 
    // result = 100; 
    } 
    else result = default(T); 
} 

用法:

int value; 
string text; 

Assign(value); // <<< should set value to 100 
Assign(text); // <<< should set text to "hello" 

我的问题是你如何编写代码来设置这些值即。在评论部分缺少的代码。

感谢您的任何帮助。

回答

16

它看起来像在这种情况下,也许你这样做是要尽量避免装箱?很难说没有更多的信息,但对于这个具体的例子,它会更简单,可能不太容易出错,只需使用方法重载:

void Assign(out string value) 
{ 
    //... 
} 

void Assign(out int value) 
{ 
    //... 
} 

对于明确学习的目的是什么错在这里,你确实需要它铸造的一般类型之前将值转换为一个对象:

(T)(object)"hello world!"; 

哪个IMO是非常讨厌的,应该是最后的手段 - 当然不会使你的代码的任何清洁剂。

你做泛型参数的类型检查任何时候,这是一个很好的迹象泛型是不是你的问题的解决方案。做泛型参数类型检查会让你的代码更复杂,而不是更简单。它使一种方法负责基于类型的不同行为,而不是一系列易于更改而不会意外影响其他行为的单一方法。见Single Responsibility Principle

0

这里有一种方法:

static void Assign<T>(out T result) { 
    Type type = typeof(T); 
    if (type.Name == "String") { 
     result = (T)Convert.ChangeType("hello", typeof(T)); 
    } 
    else if (type.Name == "Int32") { 
     result = (T)Convert.ChangeType(100, typeof(T)); 
    } 
    else { 
     result = default(T); 
    } 
} 

但这种代码味道真的不好,不利于仿制药的点(而不是使用重载方法)。我希望这不会以生产代码结束,而仅仅是为了熏陶。

+0

非常感谢;这工作。 为什么我使用的通用方法的原因是为了简化我的代码。 因为“分配代码”时,才需要针对特定​​类型(例如,字符串);为每种可能的类型创建重载函数将会很糟糕。 result = default(T)//是常见行为 – 2009-11-14 22:16:48

+7

我不同意你的看法。我认为超载就是这样。只在需要时才使用泛型。 – Sheldon 2009-11-14 22:22:52

3

的一切首先是一个非常糟糕的模式。你不应该使用这种模式。也许如果你描述你真正想要达成的目标,会有更好的答案。下面

代码工作,但正如我所说编写代码这种方式是一个坏主意。

void Assign<T>(out T result) 
    { 
     Type type = typeof(T); 
     if (type.Name == "String") 
     { result = (T) ((object)"hello"); } 
     else if (type.Name == "Int32") 
     { result = (T) ((object)100); } 
     else result = default(T); 
    } 

与用法:

 int value; 
     string text; 

     Assign(out value); 
     Assign(out text); 
1
public T GetObject<T>(string val) 
{ 
    T _object = default(T); 
    _object = (T)Convert.ChangeType(val, typeof(T)); 
    return _object; 
}