C# 有没有办法在C中使用接口作为“类型别名”?

C# 有没有办法在C中使用接口作为“类型别名”?,c#,interface,primitive,type-safety,type-alias,C#,Interface,Primitive,Type Safety,Type Alias,基本上我想使用我自己的类型,而不是像int/double这样的原语,但仍然传递这些原语值。比如: interface IInt {} // My interface to represent int. If I could fake so "int" implements this, all would work. interface IPostNumber : IInt {} // Post number is an int. But int is not type safe enough

基本上我想使用我自己的类型,而不是像int/double这样的原语,但仍然传递这些原语值。比如:

interface IInt {} // My interface to represent int. If I could fake so "int" implements this, all would work.

interface IPostNumber : IInt {} // Post number is an int. But int is not type safe enough for me.

void MyFunction(IPostNumber postNumber); // My function that should accept int/IPostNumber.

MyFunction(42); // This could also work with implicit conversion, but not allowed for interfaces:(

您可以创建一个扩展方法,但该方法应该被显式调用。

您可以创建一个扩展方法,但该方法应该被显式调用。

您要找的就是这个吗

public class IInt
{
    public int TheInt;

    public IInt(int theInt)
    {
        TheInt = theInt;
    }
}
然后使用:

IInt i = new IInt(42);
MyFunction(i);
或者为int定义MyFunction,然后使用:

IInt i = new IInt(42);
MyFunction(i.TheInt);
还有一个想法:

public class IInt<T> where T : struct
{
    public T TheInt;

    public IInt(T theInt)
    {
        TheInt = theInt;
    }
}

你要找的是这个吗

public class IInt
{
    public int TheInt;

    public IInt(int theInt)
    {
        TheInt = theInt;
    }
}
然后使用:

IInt i = new IInt(42);
MyFunction(i);
或者为int定义MyFunction,然后使用:

IInt i = new IInt(42);
MyFunction(i.TheInt);
还有一个想法:

public class IInt<T> where T : struct
{
    public T TheInt;

    public IInt(T theInt)
    {
        TheInt = theInt;
    }
}

我认为您可能在寻找隐式运算符,但不幸的是,我认为C语言规范中的接口不支持隐式运算符。如果需要,您可以使用子类来完成这项工作。下面是一个例子:

public class MyInt
{
   int SomeValue;
   public TestInt(int i)
   {
       SomeValue = i;
   }

   public static implicit operator MyInt(int i)
   {
       return new MyInt(i);
   } 

   public static implicit operator int(MyInt myInt)
   {
       return myInt.SomeValue;
   }
}
要使用隐式运算符进行赋值,可以执行以下操作:

MyInt n = 3;
int x = n;

请参阅:

我认为您可能要寻找的是隐式运算符,但不幸的是,我认为C语言规范中的接口不支持隐式运算符。如果需要,您可以使用子类来完成这项工作。下面是一个例子:

public class MyInt
{
   int SomeValue;
   public TestInt(int i)
   {
       SomeValue = i;
   }

   public static implicit operator MyInt(int i)
   {
       return new MyInt(i);
   } 

   public static implicit operator int(MyInt myInt)
   {
       return myInt.SomeValue;
   }
}
要使用隐式运算符进行赋值,可以执行以下操作:

MyInt n = 3;
int x = n;

请参阅:

根据ispiro的建议,我找到了应该涵盖一切的内容

所以我声明我的接口独立于底层表示,例如

public interface IPostNumber{}
public interface IPostNumberFrom : IPostNumber{}
public interface IPostNumberTo : IPostNumber{}
它们具有完全的接口通用性,例如多重继承。然后使用具有隐式转换的泛型类进行数据表示:

public class CInt<T>
        {
            public int value;
            public static implicit operator int(CInt<T> d) => d.value;
            public static implicit operator CInt<T>(int b) => new CInt<T>() { value = b };
        }
现在我总是可以声明CString,如果一些post编号是用字符串表示的。或者一个函数可以接受IPostNumber接口本身,如果我对它进行一些分类的话。现在一个小问题是,如果我想将CInt传递给TestPostNumber,该方法必须是带有T:IPostNumber的泛型方法,如下所示:

    private int TestPostNumberInt<T>(CInt<T> i) where T : IPostNumber => i;
    private int TestPostNumberIntFrom<T>(CInt<T> i) where T : IPostNumberFrom => i;
然后,在使用隐式转换强制转换时,将不会检测到泛型类型。但我们会看看这是不是一件大事


也供以后考虑:我将有一个CJSON:CString类。据我所见,它是有效的,尽管有争议的是CJSON也可能有不同的表示,比如在某些上下文中的byte[]。但这将使事情走得更远。因此,我只需要认真思考我的领域概念的表示与接口。

根据ispiro的建议,我找到了一些应该涵盖所有内容的东西

所以我声明我的接口独立于底层表示,例如

public interface IPostNumber{}
public interface IPostNumberFrom : IPostNumber{}
public interface IPostNumberTo : IPostNumber{}
它们具有完全的接口通用性,例如多重继承。然后使用具有隐式转换的泛型类进行数据表示:

public class CInt<T>
        {
            public int value;
            public static implicit operator int(CInt<T> d) => d.value;
            public static implicit operator CInt<T>(int b) => new CInt<T>() { value = b };
        }
现在我总是可以声明CString,如果一些post编号是用字符串表示的。或者一个函数可以接受IPostNumber接口本身,如果我对它进行一些分类的话。现在一个小问题是,如果我想将CInt传递给TestPostNumber,该方法必须是带有T:IPostNumber的泛型方法,如下所示:

    private int TestPostNumberInt<T>(CInt<T> i) where T : IPostNumber => i;
    private int TestPostNumberIntFrom<T>(CInt<T> i) where T : IPostNumberFrom => i;
然后,在使用隐式转换强制转换时,将不会检测到泛型类型。但我们会看看这是不是一件大事


也供以后考虑:我将有一个CJSON:CString类。据我所见,它是有效的,尽管有争议的是CJSON也可能有不同的表示,比如在某些上下文中的byte[]。但这将使事情走得更远。因此,只需仔细考虑我的域概念的表示与接口。

我认为您正在寻找所谓的using alias指令;使用IAccountNumber=System.Int32;可以使用,但类型系统不会确保IAccountNumber未作为IPostNumber传递。我还想用这个接口做其他接口的东西。你需要解决什么问题?这似乎是过度思考。问题:为什么要使用自定义接口而不是int、double等值类型?我认为您正在寻找所谓的using alias指令;使用IAccountNumber=System.Int32;可以使用,但类型系统不会确保IAccountNumber未作为IPostNumber传递。我还想用这个接口做其他接口的东西。你需要解决什么问题?这似乎是过度思考。问题:为什么要使用自定义接口而不是int、double等值类型?使用类或结构的主要问题是,我希望以后也通过接口继承它。我还希望避免用struct或class包装int的性能成本。@user2154768您可以定义一个接口并让IInt实现它吗?也许再解释一下为什么需要这个界面?你会用它做什么?至于性能,据我所知,如果你不打算在某个紧密的循环中多次使用它,那就不重要了。当然,这取决于您的具体场景。我将设置一些插入项,例如IPostNumberFrom:IPostNumber:IInt,例如多个层和多个继承
E我还可以使用一个单独的空IPostNumber接口,带有IPostNumberPrint:IPostNumber、IInt和IPostNumberString:IPostNumber、IString。我将使用反射来读取我的接口并生成一些图形,通过使用反射查找我的所有函数,我将使用这些图形来查找从一种类型转换到另一种类型的函数路径。然后可能会生成一些代码来生成路径的有效实现。方案B为功能参数/返回属性…@user2154768 OK。所以我没有主意了。但我确实在我的回答中又提出了一个想法——让这门课变得通用。祝你好运使用类或结构的主要问题是,我希望以后也通过接口继承它。我还希望避免用struct或class包装int的性能成本。@user2154768您可以定义一个接口并让IInt实现它吗?也许再解释一下为什么需要这个界面?你会用它做什么?至于性能,据我所知,如果你不打算在某个紧密的循环中多次使用它,那就不重要了。当然,这取决于您的具体场景。我将设置一些插入,例如IPostNumberFrom:IPostNumber:IInt,例如许多层和多重继承。我还可以使用一个单独的空IPostNumber接口,带有IPostNumberPrint:IPostNumber、IInt和IPostNumberString:IPostNumber、IString。我将使用反射来读取我的接口并生成一些图形,通过使用反射查找我的所有函数,我将使用这些图形来查找从一种类型转换到另一种类型的函数路径。然后可能会生成一些代码来生成路径的有效实现。方案B为功能参数/返回属性…@user2154768 OK。所以我没有主意了。但我确实在我的回答中又提出了一个想法——让这门课变得通用。祝你好运我在ispiro的建议中使用了隐式运算符,他们似乎做到了这一点。我在ispiro的建议中使用了隐式运算符,他们似乎做到了这一点。